TCP / IP客户端在服务器崩溃后发送数据会发生什么?

时间:2016-10-11 16:17:32

标签: c++ linux sockets tcp

我试图在客户端在tcp服务器崩溃后发送数据时测试如何处理客户端。我写了一个简单的客户端和服务器代码来提供一些可视化示例。客户端连接到tcp服务器,将数据发送到服务器,服务器读取数据。 现在我为两个实现添加一个sleep(20),所以我有时间杀死服务器进程(ctrl-c)。 客户端再次调用send()并返回消息的长度。服务器未连接,因此客户端可能不会收到ACK数据包。我假设客户端获取RST数据包但send()已经返回。客户端第三次调用send(),但这次,进程突然结束而没有显示任何错误。最后一行: cout<< rsize<< endl 以及它下面的所有内容都不会被调用,或者至少看起来像是什么。

当我运行它时,客户端会打印前两个消息的rsize值,但不会输出最后一个消息的值。服务器仅打印收到的第一条消息。

我的问题是(1)为什么会发生这种情况?以及(2)如果客户端突然终止,我如何才能正确处理服务器崩溃?

我已经阅读了与该主题相关的其他问题,但他们没有显示如何处理此问题的实际代码。

客户端代码

#include <iostream>
#include <cerrno>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;

int main()
{
  int serverPort = 65003;
  char serverHost[] = "127.0.0.1";
  int mySocket;
  int bufferSize = 524388;
  char responseBuffer[bufferSize];

  struct sockaddr clientAddr;
  struct sockaddr_in serverAddr;
  struct in_addr ipv4addr;

  serverAddr.sin_family = AF_INET;
  mySocket = socket(AF_INET, SOCK_STREAM, 0);
  serverAddr.sin_port = htons (serverPort);
  inet_aton(serverHost, &serverAddr.sin_addr);

  connect(mySocket, (struct sockaddr*) &serverAddr, sizeof(serverAddr));
  int addrLen = sizeof(serverAddr);
  getsockname(mySocket, &clientAddr, (socketlen_t*)&addrLen);

  ssize_t rsize;

  char requestMsg [] = "<This is my test Msg>";
  cout << rsize << endl;
  rsize = send(mySocket, requestMsg, strlen(requestMsg), 0);
  if (rsize != (ssize_t)strlen(requestMsg))
  {
    cout << strlen(requestMsg) << endl;
    cout << strerror(errno) << endl;
  }

  sleep(20);
  char requestMsg2 [] = "<This is my 2nd test Msg>";
  rsize = send(mySocket, requestMsg2, strlen(requestMsg2), 0);
  cout << rsize << endl;
  if (rsize != (ssize_t)strlen(requestMsg2))
  {
    cout << strlen(requestMsg2) << endl;
    cout << strerror(errno) << endl;
  }

  char requestMsg3 [] = "<This is my 3rd test Msg>";
  rsize = send(mySocket, requestMsg3, strlen(requestMsg3), 0);
  cout << rsize << endl;
  if (rsize != (ssize_t)strlen(requestMsg3))
  {
    cout << strlen(requestMsg3) << endl;
    cout << strerror(errno) << endl;
  }

  return 0;
}

服务器代码

#include <iostream>
#include <cerrno>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;

int main()
{
  int mySocket, connSocket, serverPort;
  socketlen_t clientLen;
  struct sockaddr_in serverAddr, clientAddr;
  int bufferSize = 256;
  char buffer[bufferSize];
  ssize_t rsize;

  mySocket = socket(AF_INET, SOCK_STREAM, 0);
  memset(&serverAddr, 0, sizeof(serverAddr));
  serverPort = 65003;
  serverAddr.sin_family = AF_INET;
  serverAddr.sin_addr.s_addr = INADDR_ANY;
  serverAddr.sin_port = htons(serverPort);

  bind(mySocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
  listen(mySocket,1);
  clientLen = sizeof(clientAddr);
  connSocket = accept(mySocket, (struct sockaddr *) &clientAddr, &clientLen);

  memset(&buffer, 0, sizeof(buffer));
  rsize = read(connSocket, buffer, 255);
  cout << buffer << endl;

  sleep(20);

}

0 个答案:

没有答案