|
Try to post the relevant code.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
I'm new in sockets programming especially in the asynchronous sockets. I'm writing a server and client apps with asynchronous sockets to (of course) exchange data between them.
This is the code for the client app:
<br />
int SocketClient::CreateSocket(HWND hwnd)<br />
{<br />
char cName[20];<br />
hostent * hostInfo;<br />
WSADATA wsStartup;<br />
WORD wVersion = MAKEWORD(2, 0);<br />
WSAStartup(wVersion, &wsStartup);<br />
currSocket = socket(AF_INET, SOCK_STREAM, 0);<br />
if(currSocket == INVALID_SOCKET)<br />
{<br />
MessageBox(NULL, "Socket não criado", "Erro", MB_OK);<br />
return -1;<br />
}<br />
gethostname(cName, 20);<br />
hostInfo = gethostbyname(cName);<br />
for(int i = 0 ; i < 8 ; i++)infosSocket.sin_zero[i] = 0;<br />
infosSocket.sin_family = AF_INET;<br />
infosSocket.sin_port = htons(2500);<br />
infosSocket.sin_addr = *((in_addr*)hostInfo->h_addr_list[0]);<br />
WSAAsyncSelect(currSocket, hwnd, WM_ASYNCMSG, FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE);<br />
return 0;<br />
}<br />
<br />
int SocketClient::ConnectToServer(HWND hwnd)<br />
{<br />
int iReturn = 0;<br />
iReturn = connect(currSocket, (sockaddr*)&infosSocket, sizeof(infosSocket));<br />
if(iReturn == SOCKET_ERROR)<br />
{<br />
char cTemp[10];<br />
int iResult = WSAGetLastError();<br />
itoa(iResult, cTemp, 10);<br />
MessageBox(NULL, cTemp, "", MB_OK);<br />
return -1;<br />
}<br />
WSAAsyncSelect(currSocket, hwnd, WM_ASYNCMSG, FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE);<br />
MessageBox(NULL, "OK", "", MB_OK);<br />
return 0;<br />
}<br />
And this is the server code:
<br />
int SocketServer::CreateSocket(HWND hwnd)<br />
{<br />
SocketServer::iBytesRecieved = 0;<br />
int iReturn = 0;<br />
WSADATA wsStartup;<br />
WORD wVersion = MAKEWORD(2,0);<br />
WSAStartup(wVersion, &wsStartup);<br />
currSocket = socket(AF_INET, SOCK_STREAM, 0);
if(currSocket == INVALID_SOCKET)<br />
{<br />
MessageBox(NULL, "Socket não criado", "Erro", MB_OK);<br />
return -1;<br />
}<br />
socketInfo.sin_family = AF_INET;<br />
socketInfo.sin_port = htons(2500);<br />
socketInfo.sin_addr.s_addr = INADDR_ANY;<br />
for(int i = 0 ; i < 8 ; i++)socketInfo.sin_zero[i]=0;<br />
iReturn = bind(currSocket, (sockaddr*)&socketInfo, sizeof(sockaddr));
if(iReturn == SOCKET_ERROR)<br />
{<br />
int iError = WSAGetLastError();<br />
MessageBox(NULL, "Erro", "", MB_OK);<br />
return iError;<br />
}<br />
WSAAsyncSelect(currSocket, hwnd, WM_ASYNCMSG, FD_ACCEPT|FD_CLOSE|FD_READ|FD_WRITE);<br />
return 0;<br />
}<br />
<br />
void SocketServer::ListenConnections()<br />
{<br />
listen(currSocket, 5);<br />
}<br />
<br />
SOCKET SocketServer::AcceptConnection(HWND hwnd)<br />
{<br />
SOCKET tempSocket = 0;<br />
int iSize = sizeof(sockaddr_in);<br />
tempSocket = accept(currSocket, (sockaddr*)&socketInfo, &iSize);<br />
WSAAsyncSelect(tempSocket, hwnd, WM_ASYNCMSG, FD_READ|FD_WRITE|FD_CLOSE);<br />
return tempSocket;<br />
}<br />
Now the questions:
The SendData and RecieveData funcs that contains send and recv funcs respectively, needs to be in a thread for that FD_READ and FD_WRITE messages will be sended?
In the ConnectToServer func, when I start the server and the client app, I've received WSAEWOULDBLOCK message. If I call this funcition again I receive the WSAEISCONN message. This means that my socket is connected? If so, why I receive the WSAEWOULDBLOCK message first?
In some sites that I've readed some tutorials, they say that, in the FD_WRITE message I need to have some caution because this message is sent when there are more space in the buffer with which to write data. Can someone explains tis to me?
Sorry for this long post fellows, but I need a help in this.
|
|
|
|
|
Alex Cutovoi wrote: The SendData and RecieveData funcs that contains send and recv funcs respectively, needs to be in a thread for that FD_READ and FD_WRITE messages will be sended?
Since you've used WSAAsyncSelect() specifying the FD_READ and FD_WRITE flags you will be notified
when there is data available to be read from the socket and when the socket is ready to accept
send data. This notification will be in the form of a window message (WM_ASYNCMSG) so you could
send/recv data on the UI htread that processes this message. You can also send/recv on other
threads. Just make sure you use some form of synchronization - sockets ops are not thread safe.
Alex Cutovoi wrote: In the ConnectToServer func, when I start the server and the client app, I've received WSAEWOULDBLOCK message. If I call this funcition again I receive the WSAEISCONN message. This means that my socket is connected? If so, why I receive the WSAEWOULDBLOCK message first?
WSAEWOULDBLOCK indicates that an asynchronous socket operation has started but didn't complete
immediately. If you want to be notified when a connect() call completes then you should add the
FD_CONNECT flag to your WSAAsyncSelect() flags.
Alex Cutovoi wrote: In some sites that I've readed some tutorials, they say that, in the FD_WRITE message I need to have some caution because this message is sent when there are more space in the buffer with which to write data. Can someone explains tis to me?
Read the details of using FD_WRITE carefully in the docs. From WSAAsyncSelect() -
"The FD_WRITE event is handled slightly differently. An FD_WRITE message is posted when a socket
is first connected with connect or WSAConnect (after FD_CONNECT, if also registered) or accepted
with accept or WSAAccept, and then after a send operation fails with WSAEWOULDBLOCK and buffer
space becomes available. Therefore, an application can assume that sends are possible starting
from the first FD_WRITE message and lasting until a send returns WSAEWOULDBLOCK. After such a
failure the application will be notified that sends are again possible with an FD_WRITE message."
Always check the return code on send() and recv() calls to make sure the number of bytes requested
were actually sent or received. A send() or recv() is successful even if only ONE byte gets sent
or received. You'll need to be ready to send remaining unsent bytes and/or receive remaining
unreceived bytes.
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
Thanks again Mark, I've suspected that WSAEWOULDBLOCK message indicates what you said. I comproved this studying some code samples and noticing the WSAEISCONN message. Just a question of pay attention. FYI, I'm developing my apps with Win32, not a single gout of MFC.
I'm very new in this subject, I'm developing my app based on your answer about my question of sockets: Socket curious error
Very thanks.
I have some questions yet:
Mark Salsbery wrote: Since you've used WSAAsyncSelect() specifying the FD_READ and FD_WRITE flags you will be notified
when there is data available to be read from the socket and when the socket is ready to accept
send data. This notification will be in the form of a window message (WM_ASYNCMSG) so you could
send/recv data on the UI thread that processes this message. You can also send/recv on other
threads. Just make sure you use some form of synchronization - sockets ops are not thread safe.
So, do I need to put the SendData and RecieveData functions in a thread right? Can you give me a sample?
Mark Salsbery wrote: Always check the return code on send() and recv() calls to make sure the number of bytes requested
were actually sent or received. A send() or recv() is successful even if only ONE byte gets sent
or received. You'll need to be ready to send remaining unsent bytes and/or receive remaining
unreceived bytes.
This is the hard part, how can I check in app there unsent bytes?
This is a topic that I don't domain yet, I'll be very grateful if you can answer my questions again.
|
|
|
|
|
Alex Cutovoi wrote: So, do I need to put the SendData and RecieveData functions in a thread right? Can you give me a sample?
You don't need to but you can. If there's so much data being sent and received that it degrades
the UI performance then it's probably a good idea. If you only transfer small amounts not very
often then you could leave your send/recv calls on the UI thread.
Alex Cutovoi wrote: This is the hard part, how can I check in app there unsent bytes?
The return value of the socket send() and recv() APIs are slightly different.
Both return SOCKET_ERROR if an error occurs, which means no bytes were transferred. For an async
socket if the error was WSAEWOULDBLOCK then it means data could't be transferred right away (no
bytes were received or send buffer is full) so you'll need to try again.
For send(), a successful return value is the number of bytes sent, which may not be all the bytes
you requested to be sent.
For recv(), a successful return value is the number of bytes received, which may not be all the
bytes you requested to be received. If recv() returns 0 that means the connection has been
closed.
So, a generic example of handling these return values could be something like this:
int nBytesToRecv = ...;
BYTE *pRecvBytes = ...;
while (nBytesToRecv > 0)
{
int nBytesReceived = ::recv(sock, (char*)pRecvBytes, nBytesToRecv, 0);
if (nBytesReceived == SOCKET_ERROR)
{
int nSockError = ::WSAGetLastError();
if (nSockError != WSAEWOULDBLOCK)
{
break;
}
}
else
{
nBytesToRecv -= nBytesReceived;
if (nBytesToRecv > 0)
pRecvBytes += nBytesReceived;
}
}
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
Very thanks mike, I have a direction now.
But one more thing, I want to send a struct between the apps. To fill the nBytesToRecv var, in my case, just I call the sizeof() func to fill it?
Thanks for the help in this topic.
|
|
|
|
|
Alex Cutovoi wrote: To fill the nBytesToRecv var, in my case, just I call the sizeof() func to fill it?
Generally yes. As long as the two ends use the same byte ordering for multi-byte numeric types
(int, etc.). Both ends should be compiled using the same structure padding as well.
Mark
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
Thanks mark, now I get some more knowledge to code my app
|
|
|
|
|
Hi all,
I am making one win32 application using VC++.NET 2003. I want to make screen capturing for specific area on screen as a part of my application. I know how to capture whole screen or a window using CreateCompatibleBitmap(); but I don’t know how can I capture specific rectangle area from it. Can I get some help please?
Thanks in Advance,
Priyank
|
|
|
|
|
See this[^] article.
/ravi
|
|
|
|
|
Thanks but that capturing tool is not capturing sepcific area. I have Left, Right, Top and Bottom coordinates of screen. I want to capture only that area.
Priyank
|
|
|
|
|
priyank_ldce wrote: that capturing tool is not capturing sepcific area.
Interesting. The opening sentence "This article demonstrates the methods of capturing different portions of the screen." and the reference to this method left me thinking otherwise:
HBITMAP CopyScreenToBitmap(LPRECT lpRect); /ravi
|
|
|
|
|
How about capure the entire screen and then use a bitblt copy operation to extract the part you want? Seems reasonable enough to me unless you don't think the entire screen will fit into memory or some other simple constraint such as that
|
|
|
|
|
or how about just capturing the rect you want the same way you capture en entire screen except
create the destination bitmap the size of the rect and use the correct offsets/size in a BitBlt()
call.
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
I am working with tool bar in dialog based application. How to show tool tip help for the tool bar items? Thanks in advance.
|
|
|
|
|
|
See this[^] article.
/ravi
|
|
|
|
|
I am developing a flight simulator application that has a MDI interface to entry settings and read some status information. However, I am little lost where i should place the main state machine/loop that controls all of the motion based incoming UDP sockets messasges. Right now, I envision creating a class that starts it's own thread calling running that will recieve and process all the motions movement. Is this a good way to setup a systems. The UDP socket can recieve up to 30 motion commands per second.
//Peusodo Code
<br />
<br />
void service_motion::Runnning( void ) <br />
{<br />
UDP_Socket.GetPacket( &cmdpkt );<br />
<br />
switch( state )<br />
{<br />
<br />
case BOARDING:<br />
if( inputs == OK ) <br />
state = DOCKED_DOWN;<br />
break;<br />
<br />
case DOCKED_DOWN:<br />
if( cmdpkt.opcode == START_GAME )<br />
state = RUNNING;<br />
break;<br />
<br />
<br />
case PAUSED:<br />
break;<br />
<br />
case RUNNING:<br />
if( cmdpkt.opcode == PAUSE )<br />
state = PAUSED;<br />
<br />
if( cmdpkt.opcode == STOP)<br />
{<br />
stop_motion();<br />
state = PAUSED;<br />
}<br />
<br />
break;<br />
<br />
case EMERGENCY:<br />
<br />
break;<br />
<br />
case RECOVERY:<br />
break;<br />
<br />
<br />
<br />
Scott Dolan
Jernie Corporation
Engineering & Manufacturing
Software, Hardware, & Enclosures
|
|
|
|
|
ScotDolan wrote: switch( state )
That's not a state machine
led mike
|
|
|
|
|
led mike wrote: That's not a state machine
A switch statement is a perfectly fine way to implement a FSM. I'm curious why you feel otherwise?
/ravi
|
|
|
|
|
Ravi Bhavnani wrote: A switch statement is a perfectly fine way to implement a FSM.
Whatever
led mike
|
|
|
|
|
Can this be accomplished using Events or messages? Does it make more sense to read the commands from UDP socket outside the Running Thread and send messages and/or events to FSM?
Scott Dolan
Jernie Corporation
Engineering & Manufacturing
Software, Hardware, & Enclosures
|
|
|
|
|
ScotDolan, I have no idea what your project parameters are:
A flight simulator
A UDP Socket
30 UDP commands per second
controls all the motion
EMERGENCY - Disables network commands
What commands? From what? Why a Socket? What Motion? What is "EMERGENCY"? What does "Disables network commands" mean?
What is the desired "result" of all this?
led mike
|
|
|
|
|
Dude, what are you talking about?
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
|