recv incoming traffic from server
I have the following function setup to receive the data from server every 2 minutes. For the first time i call the function it seems to work but then it freezes at the recv
call which never returns. and would i need to allocate the buffer on each call even if the server has nothing to send?
#define RCVBUFSIZE 32
void Receive()
{
UINT totalBytesRcvd = 0, bytesRcvd = 0;
char buffer[RCVBUFSIZE]; /* Buffer for string */
/* Receive up to the buffer size (minus 1 to leave space for
a null terminator) bytes from the sender */
bytesRcvd = recv(sockClient, buffer, RCVBUFSIZE开发者_如何学Go - 1, 0);
if (bytesRcvd)
{
buffer[bytesRcvd] = '\0';
MessageBox(0, buffer, 0, 0); //some way to display the received buffer
}
else if (bytesRcvd == SOCKET_ERROR)
{
return;
}
}
(1) Your buffer is not really allocated, it's residing on the stack. You typically need not worry about using 32 bytes on the stack.
(2) recv
is supposed to block until it has something to receive. You can get around that by using non-blocking sockets or by using select
. Please see here for reference.
In particular, you may
(2a) Use ioctlsocket to set your socket to non-blocking mode. Then, when you call read
and there is nothing to read, you'd get the error EWOULDBLOCK
.
unsigned long non_blocking = 1;
ioctlsocket (sockClient, FIONBIO, &non_blocking);
Then reading becomes
bytesRcvd = recv(sockClient, buffer, RCVBUFSIZE - 1, 0);
if (bytesRcvd == -1) {
if (WSAGetLastError() == EWOULDBLOCK) {
// nothing to read now
} else {
// an actual error occurred
}
} else {
// reading was successful. Call to MsgBox here
}
(2b) Or, you may call select to determine whether there is data to read, before actually calling read
.
struct timeval timeout;
timeout.tv_usec = 0;
timeout.tv_sec = 0;
fd_set r;
FD_ZERO (&r);
FD_SET (sockClient, &r);
switch (select (sockClient + 1, &r, NULL, NULL, &timeout)) {
case -1:
// error
break;
case 0:
// nothing to read
break;
case 1:
// you may call read ()
break;
}
精彩评论