Я пытаюсь написать клиент-серверное приложение, используя протокол 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, когда я закрою сокет?