2

I have a simple client server program that I made but the main issue is that once a connection is established between the client and server, if the client closes the program, the server repeatedly executes the last message and that creates huge problems sometimes. So what I want to is if there is any function that I can call to get the state of a SOCKET structure so if the client closes the program, the server will know to stop. I just need the function what to look for from the function for a bad socket. By the way I am writing this program in Win32 c. I tried if(mySocket==SOCKET_ERROR) which didn't seem to work... unless I used it wrong. I'm just beginning networking.

if(!sockServer.RecvData( recMessage, STRLEN )){return 0;}
// where
bool Socket::RecvData( char *buffer, int size )
{
    int i = recv( mySocket, buffer, size, 0 );
    if(!i){return false;}
    buffer[i] = '\0';
    return true;
}  //this isn't working
Iowa15
  • 3,027
  • 6
  • 28
  • 35

2 Answers2

3

If the peer closes the socket, read() and recv() will return zero. You must be ignoring that if 'the server repeatedly executes the last message', which of course would 'create huge problems' not just 'sometimes' but always.

EDIT 1: You're also making another elementary TCP programming error: you are assuming that you receive an entire message in a single read. There are no messages in TCP, it's just a byte stream, and no 1::1 correspondence between writes and reads (send() and recv()). recv() can return zero or as few as 1 bytes. You have to organize your own message boundaries, and you have to loop until you receive an entire message you can deal with.

EDIT 2: You are also ignoring all errors in your receive method. You must look for recv() returning -1`, and not proceed with the logic that processes the data you were trying to read. At a minimum you should call perror() or check errno or whatever the Winsock equivalent is.

When you get either an error or an EOS you must stop looping, close the socket, forget about the connection, and forget about this client.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • hmm that didn't seem to work. I have implemented what i think you told me do above in my edit – Iowa15 Oct 16 '12 at 23:45
  • @Iowa15 You have to do more than that. You have to observe that your methods returned `false` and `zero` respectively; exit whatever loop is driving this logic; close the socket; and do whatever other housekeeping is required to forget about this socket, this client, this connection. – user207421 Oct 17 '12 at 00:03
1

How about listening for FD_CLOSE in your Main message proc? you are using WSAAsyncSelect with FD_CLOSE right?

Gunner
  • 5,780
  • 2
  • 25
  • 40
  • He wants to detect whether the client side ended the connection. The server side socket might still be valid then. No `FD_CLOSE` would not be issues, as the server side socket would not be `close()`d automagically, when the client ends. – alk Oct 17 '12 at 08:05