0
votes

I am developing a simple server/client chat app in c++ using unix sockets and there is one thing bothering me.

If I run the chat client in terminal (i'm using a mac) and close the client with CTRL + C the four-way handshake is done and connection closes correct.

If I instead choose to close the terminal window, in which the client is running, the client sends a bunch of packets to the server.

Close client with CTRL + C:

enter image description here

Close client by closing terminal window:

enter image description here

Would be great if someone could explain to me what is happening.

Client code:

 void writeString(int FD, const char* data, size_t n){
   size_t bytesLeft = n;
   ssize_t bytesWritten = 0;
   const char *cBuffer = (char*) data;
   while ((bytesWritten = write(FD, cBuffer, bytesLeft)) > 0) {
    bytesLeft -= bytesWritten;
    cBuffer += bytesWritten;
   }
 }

 bool writeInt(int FD, int intToWrite){
   intToWrite = htonl(intToWrite);
   write(FD, &intToWrite, sizeof(intToWrite));
 }  

void writeMessage(int FD, int type, int ID, string message){
  if(type == 1){
    int messageSize = (int) message.length();
    writeInt(FD, type);
    writeInt(FD, ID);
    writeInt(FD, messageSize);
    writeString(FD, message.c_str(), messageSize);
  }
}

while (!connectionClosed) {
FD_SET(socketFD, &rset);
FD_SET(0, &rset);
int maxfd = max(0, socketFD) + 1;

select(maxfd, &rset, NULL, NULL, NULL);

if(FD_ISSET(0, &rset)){
  getline(cin, input);
  writeMessage(socketFD, 1, ID, input);
}else if(FD_ISSET(socketFD, &rset)){
  int type = 0;
  if(readInt(socketFD, type) == 0)
    connectionClosed = true;
  readMessage(socketFD, type, ID);
}
}

close(socketFD);
1
Can't tell for sure, but you probably need to handle SIGHUP to catch the terminal window going away, then close the socket and exit.Nikolai Fetissov
But why does it keep sending packets, even after the app is closed?Carlj901
Are you sure your app is gone? Closing a window on a Mac does not exit the application. Look at the list of processes to be sure.Nikolai Fetissov
It takes a few seconds before it closes and during that time messages are sent. I'm confused.Carlj901
From the packet dump it looks like one side is trying to send, but the other is not acknowledging. Again, try catching SIGHUP and maybe SIGSTOP and closing socket and exiting.Nikolai Fetissov

1 Answers

0
votes

My guess is when you close the terminal with the close button it is sending some standard terminal command to end the session to the PTY. Since your chat app is running the commands get intercepted by your chat app instead and forwarded to the server.

For example the telnet protocol includes control codes for a lot of things including interrupting and aborting the running process.

Have you looked at the actual packet contents that is being sent?

Regarding PSH (push) it's explained pretty well here for example:
http://packetlife.net/blog/2011/mar/2/tcp-flags-psh-and-urg/

You might also want to add logging to disk in your client app, so that you can later inspect what was going on as you're closing the terminal window.

Or even attach a debugging session to your running client from another terminal window.