Winsock计划导致港口耗尽
发表不同的帖子,有助于解释我问题症状的来源: https://superuser.com/questions/1348102/windows-10-ephemeral-port-haustion-exhaustion-but-netstat-says-otherwise-
>我自己创造了所有港口。
请参阅前2个结果-6072端口-6072端口,一个实例使用,545由545 by另一个 - 如果我理解该结果正确设置。
列出了2个实例,因为有2个实例运行 - 这是一个每60秒连接到机器的程序,询问它是否具有信息,请检索,然后关闭连接。
它是使用Winsock TCP连接用C ++编写的。
有人可以建议我修改以防止这种情况发生吗?
目前,在运行程序的大约一个半月后,我们遇到了无法“由于时间和日期差”而无法进入服务器的问题,即使时间和日期与NTP完全同步服务器和其他计算机,当然,它将抓住能够连接到任何东西。
我们仍然可以通过IP地址直接连接到服务器,而不是主机名。
除了重新启动服务器外,我还没有找到任何解决方案。
连接的机制是一种简单而原始的:
void Connect(string ipA)
{
// Initialize Winsock
Debug("Connecting to socket...");
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
{
Debug("Client: Error at WSAStartup().");
}
else
{
Debug("Client: WSAStartup() is OK.");
}
// Create a SOCKET for connecting to server
u_long mode = (u_long)0;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
GPT_ATTRIBUTE_NO_BLOCK_IO_PROTOCOL;
if (ConnectSocket == INVALID_SOCKET)
{
printf("Client: Error at socket(): %ld.\n", WSAGetLastError());
WSACleanup();
return;
}
iResult = ioctlsocket(ConnectSocket, FIONBIO, &mode);
if (iResult != NO_ERROR)
printf("ioctlsocket failed with error: %ld\n", iResult);
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr(ipA.c_str());
clientService.sin_port = htons(port);
// Connect to server.
if (connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
{
Debug("Connection failed...");
WSACleanup();
return;
}
else
Debug("Connection successful.");
}
此方法以作为参数提供的IP地址调用并导致成功的连接。
之后,使用这些请求响应数据包发送了几个:
void SendPacket(int iResult, SOCKET ConnectSocket, const char* a)
{
Debug("Sending message to CW: " + (string)a);
iResult = send(ConnectSocket, a, strlen(a), 0);
if (iResult == SOCKET_ERROR) {
Debug("Send failed");
closesocket(ConnectSocket);
WSACleanup();
}
else
Debug("Send successful.");
}
并且
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
一旦完成特定的会话,我们将关闭连接:
void ShutDown(int iResult, SOCKET ConnectSocket)
{
iResult = shutdown(ConnectSocket, SD_SEND);
Debug("Shutting down socket...");
if (iResult == SOCKET_ERROR) {
Debug("Shutdown failed");
closesocket(ConnectSocket);
WSACleanup();
}
else
Debug("Shutdown successful.");
}
有几百条代码可以处理收到的数据,但是这些代码不会是相关,因为他们不处理任何类型的网络连接。
要说我没有C ++的经验是轻描淡写,我只是使用基本的MS模板将其拍打在一起,直到它完全按照我们的需要工作,此后就没有触摸过。
因此,如果有人可以指出我可以更改以避免港口疲劳,我将非常感激。
只是为了添加一点清晰度 - 该程序将始终连接到同一端口上的机器。我试图将传出连接(从Windows)端口绑定到同一连接,但是我一直没有成功 - 浪费了很多小时,试图使这1件简单的事情正确,但我认为这可以解决我的问题。
Going off a different post that helped explain the source of the symptoms of my issue: https://superuser.com/questions/1348102/windows-10-ephemeral-port-exhaustion-but-netstat-says-otherwise
I am having a very similar issue - except the problem is the program eating up all the ports is one I created myself.
See the top 2 results - 6072 ports used by one instance and 545 by the other - if I understand that result set correctly.
There are 2 instances listed as there are 2 instances running - this is a program that connects to a machine every 60 seconds, asks if it has information, retrieves it if it does, and then closes the connection.
It was written in C++ using winsock TCP connections.
Is there anything someone could suggest I modify to prevent this from happening?
Currently, after about a month and a half of the program running, we run into the issue of not being able to RDC into the server "due to a time and date difference" even though the time and date are perfectly in sync with the NTP server and the rest of the computers, and of course it will seize being able to connect to anything.
We can still connect to the server directly through IP address, but not hostname.
I haven't yet found any solutions to this other than rebooting the server.
The mechanism for connecting is a simple and primitive:
void Connect(string ipA)
{
// Initialize Winsock
Debug("Connecting to socket...");
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
{
Debug("Client: Error at WSAStartup().");
}
else
{
Debug("Client: WSAStartup() is OK.");
}
// Create a SOCKET for connecting to server
u_long mode = (u_long)0;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
GPT_ATTRIBUTE_NO_BLOCK_IO_PROTOCOL;
if (ConnectSocket == INVALID_SOCKET)
{
printf("Client: Error at socket(): %ld.\n", WSAGetLastError());
WSACleanup();
return;
}
iResult = ioctlsocket(ConnectSocket, FIONBIO, &mode);
if (iResult != NO_ERROR)
printf("ioctlsocket failed with error: %ld\n", iResult);
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr(ipA.c_str());
clientService.sin_port = htons(port);
// Connect to server.
if (connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
{
Debug("Connection failed...");
WSACleanup();
return;
}
else
Debug("Connection successful.");
}
This method is called with the IP address supplied as a parameter and results in a successful connection.
After that, several request-response packets are sent using these:
void SendPacket(int iResult, SOCKET ConnectSocket, const char* a)
{
Debug("Sending message to CW: " + (string)a);
iResult = send(ConnectSocket, a, strlen(a), 0);
if (iResult == SOCKET_ERROR) {
Debug("Send failed");
closesocket(ConnectSocket);
WSACleanup();
}
else
Debug("Send successful.");
}
And
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
And once we're done with the particular session, we close the connection:
void ShutDown(int iResult, SOCKET ConnectSocket)
{
iResult = shutdown(ConnectSocket, SD_SEND);
Debug("Shutting down socket...");
if (iResult == SOCKET_ERROR) {
Debug("Shutdown failed");
closesocket(ConnectSocket);
WSACleanup();
}
else
Debug("Shutdown successful.");
}
There are a couple hundred lines of code that handles the data received, but those won't be relevant as they don't deal with any sort of network connection.
To say I have no experience with C++ would be an understatement, I simply slapped this together using basic MS templates until it worked exactly as we needed it and haven't touched it since.
So if there is anything someone can point out that I could change to avoid port exhaustion, I would be very grateful.
Just to add a bit of clarity - the program will ALWAYS connect to the machine on the same port. I have tried to bind the outgoing connection (from Windows) port to the same one also, but I have been unsuccessful - wasted many hours trying to get this 1 simple thing right, but I presume that would resolve my issues.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我看到您正在调用
shutdown
完成连接后,如果我们咨询文档我们看到:我认为与插座相关的任何端口仍在使用中。
在该页面上,我们还阅读了:
因此,总的来说,我会调用
colleesocket
而不是关闭
,然后在需要时请从Winsock请求新套接字。I see that you are calling
shutdown
when you are done with a connection and if we consult the documentation for that we see:Which I take to mean that any ports associated with the socket remain in use.
Further down that page, we also read:
So, all-in-all, I would call
closesocket
instead ofshutdown
and then request a new socket from Winsock when you need one.