【发布时间】:2019-02-27 03:43:29
【问题描述】:
我正在尝试使用 udp 协议编写客户端服务器应用程序,但我遇到了连接结束问题。
我打开两个套接字(一个是“服务器”,另一个是“客户端”),当服务器从客户端异步接收时,客户端向他发送一条简单的消息,打印到控制台。
经过一段时间的睡眠(以确保服务器将再次调用 recv)客户端和服务器套接字关闭。
在这一点上,我预计 recv 将返回 -1 并且异步将结束。
但实际发生的是,recv 永远卡住了*。
如果就在关闭套接字之前我发送了一个空包(在代码中将 sendToMakeExit 变量设置为 true),recv 将返回该空包,并且仅在下一次调用后才返回 -1,尽管套接字在第一次调用中已关闭。
const bool sendToMakeExit = false;
const int port = 2000;
const auto addr = "127.0.0.1";
int serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
sockaddr_in target;
target.sin_family = AF_INET;
target.sin_port = htons(port);
inet_pton(AF_INET, addr, &target.sin_addr);
bind(serverSocket, (sockaddr *) &target, sizeof(target));
auto readAsync = std::async(std::launch::async, [&serverSocket] {
const int MAX_READ = 4096;
char readBuf[MAX_READ];
ssize_t actualRead;
do {
actualRead = recv(serverSocket, readBuf, MAX_READ, 0);
if (actualRead > 0) {
cout << readBuf << endl;
}
} while (actualRead != -1);
});
int clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
connect(clientSocket, (sockaddr *) &target, sizeof(target));
this_thread::sleep_for(chrono::seconds(1));
send(clientSocket, "test", 5, 0);
this_thread::sleep_for(chrono::seconds(1));
close(clientSocket);
if (sendToMakeExit) {
sendto(serverSocket, nullptr, 0, 0, (sockaddr *) &target, sizeof(target));
}
close(serverSocket);
*如果我在调试中运行此代码并在 recv 意外卡住时创建新断点,recv 返回 -1。
当我关闭套接字时,如何让 recv 返回 -1?
【问题讨论】:
-
你的代码是C++,为什么要标记C?
-
顺便说一句,当对等方已按顺序关闭另一个时,至少流套接字返回 0