djkelly
asked on
recv() function works well in Windows NT but only blocks in Windows XP
I have a small program that sends and receives data from a server via UDP. It has worked well for the past 3 years on a Windows NT box. It was built on a Visual C++ 6.0 compiler. I am trying to get the same software to run on a Windows XP Pro platform. The odd thing is that the software runs correctly as long as I run it from within the development environment. But as soon as I build a release version and run the executable, the software blocks on the recv() function. It is like it goes deaf. I even tried to disable the debug optimizations in Project Settings thinking that something in the build environment was making the software work. It didn't make any difference. I am out of ideas. I have included part of my CommInit() function and PortRead() thread for added information. Any help you can give will be appreciated.
int CommInit()
{
int length = 4096;
int rval = NO_ERR;
WSADATA wsadata;
WORD version = (1 << 8) + 1; // Version 1.1
if (WSAStartup(version, &wsadata) != 0)
rval = ERR_WINSOCK_INIT;
// Create client sockets
if ( (in_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
rval = ERR_OPEN_SOCKET;
// Name socket using wildcards
IN_SOCKET.sin_family = AF_INET;
IN_SOCKET.sin_port = htons(3001);
IN_SOCKET.sin_addr.s_addr = INADDR_ANY;
if (bind(in_socket, (struct sockaddr *)&IN_SOCKET, sizeof(IN_SOCKET)) < 0)
rval = ERR_BIND_SOCKET;
// Find what port the operating system assigned, and print it out
length = sizeof(IN_SOCKET);
if (getsockname(in_socket, (struct sockaddr *)&IN_SOCKET, &length) < 0)
rval = ERR_SOCKET_NAME;
return rval;
}
int WINAPI PortRead(void *p)
{
int i = 0;
// if port is initialized
if(bCommCard)
{
// while the thread is running
while(!thread_halt)
{
// read in a whole structure
if ( (i = recv(in_socket, (char *)&NetIn,
sizeof(struct NETWORK_MESSAGE_TYPE)+2, 0)) == SOCKET_ERROR )
{
printf("Print an error");
}
// process the data here
} // end of while
// destroy the thread
_endthreadex(0);
}
return 0; // a thread always returns 0
}
int CommInit()
{
int length = 4096;
int rval = NO_ERR;
WSADATA wsadata;
WORD version = (1 << 8) + 1; // Version 1.1
if (WSAStartup(version, &wsadata) != 0)
rval = ERR_WINSOCK_INIT;
// Create client sockets
if ( (in_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
rval = ERR_OPEN_SOCKET;
// Name socket using wildcards
IN_SOCKET.sin_family = AF_INET;
IN_SOCKET.sin_port = htons(3001);
IN_SOCKET.sin_addr.s_addr = INADDR_ANY;
if (bind(in_socket, (struct sockaddr *)&IN_SOCKET, sizeof(IN_SOCKET)) < 0)
rval = ERR_BIND_SOCKET;
// Find what port the operating system assigned, and print it out
length = sizeof(IN_SOCKET);
if (getsockname(in_socket, (struct sockaddr *)&IN_SOCKET, &length) < 0)
rval = ERR_SOCKET_NAME;
return rval;
}
int WINAPI PortRead(void *p)
{
int i = 0;
// if port is initialized
if(bCommCard)
{
// while the thread is running
while(!thread_halt)
{
// read in a whole structure
if ( (i = recv(in_socket, (char *)&NetIn,
sizeof(struct NETWORK_MESSAGE_TYPE)+2, 0)) == SOCKET_ERROR )
{
printf("Print an error");
}
// process the data here
} // end of while
// destroy the thread
_endthreadex(0);
}
return 0; // a thread always returns 0
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
cwwkie,
I have a external debugger running where I use the OutputDebugString() command to see where it stops in my release code. I print to my debugger before and after the recv() command. I know the thread is blocked on the recv() command.
I will try reordering the global variables although I can't imagine why the same program would work in NT.
Please explain what you have in mind with the windows firewall problem. Are you talking about our network firewall? Or is there a firewall in Windows XP that is different than in NT?
Thanks
I have a external debugger running where I use the OutputDebugString() command to see where it stops in my release code. I print to my debugger before and after the recv() command. I know the thread is blocked on the recv() command.
I will try reordering the global variables although I can't imagine why the same program would work in NT.
Please explain what you have in mind with the windows firewall problem. Are you talking about our network firewall? Or is there a firewall in Windows XP that is different than in NT?
Thanks
ASKER
cwwkie,
The windows firewall was the problem. Thank you so much.
djkelly
The windows firewall was the problem. Thank you so much.
djkelly
recv() is a blocking call by definition. I don't know why it was working in Windows NT.
If no messages are available at the socket, the receive call waits for a message to arrive. If the socket is non-blocking, -1 is returned with the external variable errno set to EWOULDBLOCK.
In your code it's better to have blocking call then to have high CPU usage in that loop:
// while the thread is running
while(!thread_halt)
{
...
}
If you like to have non-blocking call, use poll() before recv() to check if there is any data available on socket.
If no messages are available at the socket, the receive call waits for a message to arrive. If the socket is non-blocking, -1 is returned with the external variable errno set to EWOULDBLOCK.
In your code it's better to have blocking call then to have high CPU usage in that loop:
// while the thread is running
while(!thread_halt)
{
...
}
If you like to have non-blocking call, use poll() before recv() to check if there is any data available on socket.
ASKER
Nopius,
Thanks for the tip and for looking over my code. I have not used the poll() command but will give it a try.
djkelly
Thanks for the tip and for looking over my code. I have not used the poll() command but will give it a try.
djkelly
> But as soon as I build a release version and run the executable, the software blocks on the recv() function.
That does not mean there is in the call to recv, it can be in any part of your program.
I see you use some global variables. Maybe there is a buffer overrun in one of them. You can try changing the order of declaration.