我目前正在做一个小的“客户端”程序,该程序会打乱“服务器端”程序以进行多线程压力测试。这两个程序都在同一台计算机上运行,但这不应该成为问题,服务器端程序绑定在特定端口上,客户端打开临时端口范围(49152-65535)上的连接。
问题如下:在我使用了临时范围内的每个端口之前,一切正常,然后WSA在客户端应用程序中返回连接拒绝错误(10048)。
崩溃循环如下,出于可读性原因,我删除了大部分不太有趣的代码:
for (int i = 0; i < 999999;i++) // ugly, I know
{
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
getaddrinfo(argv[1], DEFAULT_PORT, &hints, &bindInfo); // used to bind beforehand
struct sockaddr_in * p = (struct sockaddr_in *)(bindInfo->ai_addr);
p->sin_port = htons(0);
// Create a SOCKET for connecting to server
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
bind(ConnectSocket, bindInfo->ai_addr, (int)bindInfo->ai_addrlen)
int _size = bindInfo->ai_addrlen;
getsockname(ConnectSocket, bindInfo->ai_addr, &_size);
char myIP[16];
unsigned int myPort;
inet_ntop(AF_INET, &p->sin_addr, myIP, sizeof(myIP));
myPort = ntohs(p->sin_port);
printf("Assigned port: %u \n", myPort);
int optval = 1;
setsockopt(ConnectSocket, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof(optval))
linger lin;
lin.l_onoff = 1;
lin.l_linger = 0;
setsockopt(ConnectSocket, SOL_SOCKET, SO_LINGER, (const char *)&lin, sizeof(int));
// Connect to server.
connect(ConnectSocket, result->ai_addr, (int)result->ai_addrlen);
freeaddrinfo(result);
// Send an initial buffer
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection
shutdown(ConnectSocket, SD_SEND);
closesocket(ConnectSocket);
}
在此循环中,我使用两个不同的sockaddr_in结构在连接之前强制在端口上进行绑定。如果在连接服务器时让操作系统绑定,也会发生此问题。
大约一分钟后,该程序将再次运行,因此我假设在短暂范围内有一个锁定计时器,不受关闭和closesocket影响。我试图只用closesocket结束连接,但无济于事。
小型控制台打印:
Bytes Sent: 46
Assigned port: 50809
Bytes Sent: 46
Assigned port: 50810
Bytes Sent: 46
Assigned port: 50811
Bytes Sent: 46
Assigned port: 50812
Bytes Sent: 46
Assigned port: 52355
Bytes Sent: 46
Assigned port: 54628
Bytes Sent: 46
Assigned port: 65535
Bytes Sent: 46
Assigned port: 49152
Unable to connect to server: 10048
缺少printfs位于系统调用检查中,为清楚起见,我将其删除。错误10048之前的最后一个连接端口也是短暂端口范围内的随机端口。
编辑关于31912162 / wsa-error-10048-when-binding-server-sockets的副本:
将SO_REUSEADDR设置为true并将延迟计时器设置为零不会改变程序的行为。 编辑的代码段即可反映出这一点