Link to home
Start Free TrialLog in
Avatar of djkelly
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
}  
Avatar of cwwkie
cwwkie

> 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.

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.
ASKER CERTIFIED SOLUTION
Avatar of cwwkie
cwwkie

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of djkelly

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

Avatar of djkelly

ASKER

cwwkie,

The windows firewall was the problem. Thank you so much.

djkelly
Avatar of Arty K
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.
Avatar of djkelly

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