CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Feb 2001
    Posts
    47

    Angry Network problem - Windows - MSG_PEEK returns dodgy values...

    OK, here's the situation. I have a game (client-server) which works in linux, but when I try and run it in windows, the networking bit doesn't work.

    The specific bit, is in the server (although the client probably doesn't work either, but they are coded symetrically, so I can fix that later). Anyway, the server has a TCP socket - called TCPSocket - which it wants to receive packets on. (I know they definately *are* send correctly).

    The packets come as 2 bytes containing the packet length, and the length bytes containing the packet. Here is the code I use to receive it (the socket is non-blocking):



    Code:
    	uint16 Length;
    	int R;
    	R = recv(TCPSocket, reinterpret_cast<char*>(&Length), 2, MSG_PEEK | MSG_NOSIGNAL | MSG_DONTWAIT);
    	if (R == 0)
    	{
    		throw TException("Client::RecvPacket", "recv() returned 0.", "Connection closed.", "NET_ERROR");
    	}
    	else if (R == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
    	{
    		cout << WSAGetLastError() << endl;
    		throw TException("Client::RecvPacket", "recv() returned SOCKET_ERROR.", "Connection closed.", "NET_ERROR");
    	}
    	else if (R == 2)
    	{
    		cout << "Got Length\n";
    		char* Buffer = new char[Length + 2];
    		R = recv(TCPSocket, Buffer, Length + 2, MSG_PEEK | MSG_NOSIGNAL | MSG_DONTWAIT);
    		if (R == 0)
    		{
    			delete[] Buffer;
    			throw TException("Client::RecvPacket::", "recv() returned 0.", "Connection closed.", "NET_ERROR");
    		}
    		else if (R == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
    		{
    			delete[] Buffer;
    			cout << WSAGetLastError() << endl;
    			throw TException("Client::RecvPacket", "::recv() returned SOCKET_ERROR.", "Connection closed.", "NET_ERROR");
    		}
    		else if (R == Length + 2)
    		{
    			recv(TCPSocket, Buffer, Length + 2, MSG_WAITALL | MSG_NOSIGNAL);
    			TNetwork::Packet P(Buffer + 2, Length);
    			delete[] Buffer;
    			return P;
    		}
    		else
    		{
    			cout << "Only received " << R << " so far. Need " << Length + 2 << endl;
    		}
    		delete[] Buffer;
    	}
    	else
    	{
    		cout << "Only received " << R << " byte of length so far. Need 2\n";
    	}

    Oh yeah, also, 2 bytes containing a UDP port number are exchaned first. That bit works.
    After that, the first length it receives it 20 (which is correct), but then the second recv(...PEEK) only ever says there are the 2 bytes of the length available. If I scrap all that and receive bytes one at a time, however, I get them all!

    Seems, MSG_PEEK doesn't work properly (or as expected).
    Oh yeah, and all the MSG_*'s except MSG_PEEK are =0 in windows...

    Any help anyone.

    Thankyou for you time

    Tim Hutt.

  2. #2
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,158
    I had the same problem, but I still don't knnow the reason.
    Doing a recv with MSG_PEEK gives you an incorrect number, but if you simply recv(), it comes up with the whole telegram.
    The problem occured when the cllient (a Java app) wrote the bytes as integers to the socket, whereas it work well when the app wrote it as a bytestream.

    I know that this might not be of any help, but - you are not alone ;-)

    Regards,
    Richard

  3. #3
    Join Date
    Feb 2001
    Posts
    47
    Thanks, I'll try rearranging it to only do one MSG_PEEK at a time... maybe that will help.

  4. #4
    Join Date
    Feb 2001
    Posts
    47
    Yes! I fixed it, by changing it like this:

    Code:
    if (!ReceivedLength)
    {
       if (recv(..., 2, ..., MSG_PEEK) == 2)
         recv(..., 2, ...);
       ReceviedLength = true;
    }
    
    if (!ReceivedLength)
      return NothingAvailable;
    
    if (recv(..., Length, MSG_PEEK) == Length)
    {
      recv(..., Length, ...);
      ReceivedLength = false;
      return Packet;
    }
    Like that, but cleaner... It works now. Thats a reaaaallly annoying bug.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured