如何确保 TCP 套接字在创建时已连接
我有一个发送 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,这对我来说太晚了,因为它已经通过了套接字创建阶段。 (为什么我没有在bind()或connect()处获得WSAEADDRINUSE?)
有没有办法可以更早地获得WSAEADDRINUSE,或者有没有办法在绑定和连接的端口范围中创建套接字?
提前致谢!
I have a client application that sends TCP packets. Currently, my application does this:
creates a socket, binds and sends the packets.
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) );
And in another thread, the application connects and sends the packets:
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() */
Now I want to specify a port range for local port, so I changed the code to
nPortNumber = nPortLow;
localaddress.sin_port = htons(nPortNumber);
and loops nPortNumber in my port range, e.g ( 4000 - 5000 ) until the bind succeeds.
Since I always start my nPortNumber from the low port, if a socket is previously created on the same port, I get the WSAEADDRINUSE error as errorCode, which is too late for me because it has already passed the socket creation stage. (Why didn't I get WSAEADDRINUSE at bind() or connect()?)
Is there a way I can get the WSAEADDRINUSE earlier or is there a way to create a socket in the port range that binds and connects?
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我无法 100% 肯定地回答,因为我应该知道您在什么时候真正获得了
WSAEADDRINUSE
。无论如何,在绑定时得不到它是正常的,因为您使用了 INADDR_ANY。 IIRC,这实际上延迟了实际连接的绑定过程(我的猜测是它随后根据远程地址的路由更改了 INADDR)。但是,据我所知,您应该在调用 connect 时实际收到错误...
I cannot answer with 100% certainty as for that I should know at which point you actually get
WSAEADDRINUSE
.IN any case, it is normal you don't get it at bind, because you use
INADDR_ANY
. IIRC, this actually delays the bind process to the actual connect (my guess is it then changes the INADDR based on routing for the remote addr). However, as far as I know, you should then actually get the error at the call of connect...