我试图在客户端在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);
}