Это на AS400 (IBM i, iSeries и др.).send() не сообщает ENOTCONN, когда клиент закрыл соединение (AS400)
У меня есть небольшая программа Java, которую я использую для отправки тестовых файлов на сервер, написанный на C++, который также работает на IBM i. В моей программе Java я устанавливаю свой тайм-аут для ответа на 5, скажем. На сервере я беспорядочно спал от 0 до 10 секунд. Когда программа Java не работает, она выдает java.net.SocketTimeoutException, закрывает сокет с .close() и завершает работу. Программа сервера просто идет вперед после сна и вызывает send(). Вещь is, send() не сработает с -1 и даст ENOTCONN. Зачем? Кроме того, inet_ntop() в сокете дает мне удаленный IP-адрес и порт, подключенные к серверу, как будто сокет все еще подключен. Поцарапал голову.
EDIT: после разочарования poll(), я обнаружил, что select() сообщит об ошибке с FD_ISSET() при установке установленных ошибок. В моем случае select() возвращает 3, указывая, что для моего одного сокета установлены 3 условия (чтение, запись и ошибка). Вы не можете узнать, что такое ошибка, по крайней мере, я еще не знаю, как это выяснить.
fd_set read_set, write_set, error_set;
FD_ZERO(&read_set);
FD_ZERO(&write_set);
FD_ZERO(&error_set);
FD_SET(sock_fd, &read_set);
FD_SET(sock_fd, &write_set);
FD_SET(sock_fd, &error_set);
struct timeval timeout;
timeout.tv_sec = 10; // reset this on every new iteration.
timeout.tv_usec = 0;
int rc = select(sock_fd + 1, &read_set, &write_set, &error_set, &timeout);
CERR << "select() returned " << rc << endl;
if (rc >= 0) {
if (FD_ISSET(sock_fd, &read_set)) {
CERR << "ready to read" << endl;
}
if (FD_ISSET(sock_fd, &write_set)) {
CERR << "ready to write" << endl;
}
if (FD_ISSET(sock_fd, &error_set)) {
CERR << "has an error" << endl;
CERR << "errno=" << errno << ", " << strerror(errno) << endl;
}
}
Похоже, что сервер не получил правильное соединение, которое было близко к рукопожатию. Возьмите трассировку пакетов и убедитесь, что серверу сказали закрыть. – user4581301
Сокеты TCP или UDP? –
TCP-сокет в этом случае –