|
-
May 9th, 2003, 02:31 AM
#1
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.
-
May 9th, 2003, 08:58 AM
#2
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
-
May 9th, 2003, 11:01 AM
#3
Thanks, I'll try rearranging it to only do one MSG_PEEK at a time... maybe that will help.
-
May 9th, 2003, 02:50 PM
#4
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|