0

我正在使用 unix 套接字在 C++ 中开发一个简单的服务器/客户端聊天应用程序,有一件事情困扰着我。

如果我在终端中运行聊天客户端(我使用的是 Mac)并使用 CTRL + C 关闭客户端,则完成四次握手并正确关闭连接。

如果我选择关闭正在运行客户端的终端窗口,则客户端会向服务器发送一堆数据包。

使用 CTRL + C 关闭客户端:

在此处输入图像描述

通过关闭终端窗口关闭客户端:

在此处输入图像描述

如果有人可以向我解释发生了什么,那就太好了。

客户端代码:

 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);
4

1 回答 1

0

我的猜测是,当您使用关闭按钮关闭终端时,它会发送一些标准终端命令来结束与 PTY 的会话。由于您的聊天应用程序正在运行,因此命令会被您的聊天应用程序拦截并转发到服务器。

例如,telnet 协议包括很多事情的控制代码,包括中断和中止正在运行的进程。

您是否查看过正在发送的实际数据包内容?

关于 PSH(推送),这里解释得很好,例如: http:
//packetlife.net/blog/2011/mar/2/tcp-flags-psh-and-urg/

您可能还想在客户端应用程序中将日志记录添加到磁盘,以便稍后在关闭终端窗口时检查发生的情况。

甚至可以从另一个终端窗口将调试会话附加到正在运行的客户端。

于 2012-12-13T19:12:46.390 回答