send()在客户端关闭连接时未报告ENOTCONN(AS400)



这是在AS400(IBM i、iSeries等)上。

我有一个小Java程序,用来将测试文件发送到用C++编写的服务器,该服务器也在IBM I上运行。在我的Java程序中,我将响应的超时设置为5。在服务器中,我随机睡眠0到10秒。当Java程序超时时,它抛出Java.net.SocketTimeoutException,用.close()关闭套接字并退出。服务器程序在睡眠后继续运行,并调用send()。问题是,send()不会因-1而失败,并给出ENOTCONN。为什么?套接字上的inet_ntop()还为我提供了连接到服务器的远程IP和端口,就好像套接字仍然连接着一样。挠我的头。

编辑:在对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;
}
}

来自人工发送

ENOTCONN

套接字未连接,也未给定目标。

换句话说,你的期望是不正确的。ENOTCONN适用于尚未连接插座的情况。这与对等断开连接无关。这种情况最终会导致ECONNRESET,但不会在第一次发送时发生,因为TCP缓冲。

按设计工作。

最新更新