如何确保TCP套接字在创建时连接

How to make sure a TCP socket connects at creation time

本文关键字:套接字 创建 连接 TCP 何确保 确保      更新时间:2023-10-16

我有一个发送TCP数据包的客户端应用程序。目前,我的应用程序这样做:创建套接字,绑定并发送数据包。

struct sockaddr_in localaddress;
localaddress.sin_port = htons(0);
localaddress.sin_addr.s_addr = INADDR_ANY;
int socket;
socket = socket(AF_INET, SOCK_STREAM, 0));
bind(socket, (struct sockaddr *)&sin,sizeof(struct sockaddr_in) );

在另一个线程中,应用程序连接并发送数据包:

struct socketaddr_in remoteaddress;
// omitted: code to set the remote address/ port etc...
nRet = connect (socket, (struct sockaddr * ) & remoteaddress, sizeof (sockaddr_in ));
if (nRet == -1)
    nRet = WSAGetLastError();
if (nRet == WSAEWOULDBLOCK) {
    int errorCode = 0;
    socklen_t codeLen = sizeof(int);
    int retVal = getsockopt(
            socket, SOL_SOCKET, SO_ERROR, ( char * ) &errorCode, &codeLen );
    if (errorCode == 0 && retVal != 0)
        errorCode = errno;
}
/* if the connect succeeds, program calls a callback function to notify the socket is connected, which then calls send() */

现在我想为本地端口指定一个端口范围,所以我将代码更改为

nPortNumber = nPortLow;
localaddress.sin_port = htons(nPortNumber);

循环我的端口范围内的nPortNumber,例如(4000 - 5000),直到绑定成功。

因为我总是从低端口开始我的nPortNumber,如果之前在同一端口上创建了套接字,我得到WSAEADDRINUSE错误作为errorCode,这对我来说太晚了,因为它已经通过了套接字创建阶段。(为什么我没有得到WSAEADDRINUSE在bind()或connect()?)

是否有一种方法我可以得到WSAEADDRINUSE更早,或者有一种方法来创建绑定和连接的端口范围套接字?

提前感谢!

我不能百分之百肯定地回答,我应该知道在什么时候你实际上得到了WSAEADDRINUSE

在任何情况下,它是正常的,你没有得到它在绑定,因为你使用INADDR_ANY。IIRC,这实际上延迟了绑定到实际连接的过程(我的猜测是,它随后会根据远程地址的路由更改INADDR)。但是,据我所知,您应该在调用connect…

时实际得到错误。