windows socket port的修改

在TCP应用程序中,双方的通信是面向连接的,在同一台计算机上的多个连接需要能相互区别。TCP协议里面是用[源IP+源Port+目的IP+目的Port]来区别两个不同连接的。也就是说,只要这四个参数中有一个以上不同,这两个连接就不同。在BBS上面看到很多人简单地认为可使用的端口个数是可建立的连接的限制因素,其实这个不对的。服务端和客户端软件的连接限制因素是不同的,下面我们分别来看看。

        在服务端软件中,会有一个端口用来监听接受客户端的连接,站在客户端的角度来看,它叫目的端口,不同计算机连接到服务端该端口的连接的IP(即源IP)必然不同,而同一台计算机的两个不同连接则使用不同的端口(即源端口)连接到服务端的。不管有几个客户端连接,服务端只使用了一个端口,服务端通过源IP和源端口来识别不同的客户。有人就会问难道服务端能接受无数个连接。理论上是这样的,但事实并非如此,因为系统每创建一个连接都要使用一定的分页内存和非页面缓冲池的内存,而计算机的内存资源不可能无限,因此服务端也不可能接受无数的连接。当连接数达到一定数目时,可能就会出现10055的错误,这个错误就是告诉你内存资源不足了。具体的内存资源和可接受连接数的限制关系有空的时候再另外写一篇。

        客户端和服务端不同,客户端每发起一个连接都要使用一个随机的端口,称为临时端口。因为端口的范围是0~65535,而1024以下的是系统保留的端口,因此理论上最多可以有65535-1024个端口可以使用,但实际测试却发现可能5000个连接都达不到就会出现10048的错误。其实这是因为windows系统设置了限制。在windows中这个临时端口默认的范围是1024~5000,也就是只有3977个可用端口,如果再多就会不行了,会出现10048的错误。当然有可能还没到达这么多个就出现内存资源不足的错误了,因为客户端和服务端一样,也会受内存资源因素的限制。但这是硬件资源上的问题,我们主要看一下怎么调整这个临时端口范围的限制。windows提供了一种方法来解决这个问题,在注册表HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters下建一个MaxUserPort的双字节值,指定最大的临时端口个数,比如改为10000,那可用的临时端口范围就是1024~10000了。该参数最大可以改到65534。

       修改MaxUserPort貌似需要重启计算机才能生效,我修改成50000后,发起5000个连接到服务端就一部分连接出现10048的错误。重启后连了近2万个连接,始终没有出现10048的错误。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Windows socket客户端代码示例,它连接到指定的服务器并发送一条消息,然后接收服务器的响应并打印出来: ```C++ #include <stdio.h> #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") int main() { // 初始化Winsock WSADATA wsaData; int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { printf("WSAStartup failed with error: %d\n", iResult); return 1; } // 创建一个socket对象 SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (clientSocket == INVALID_SOCKET) { printf("socket failed with error: %ld\n", WSAGetLastError()); WSACleanup(); return 1; } // 定义服务器的地址和端口号 sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1"); serverAddress.sin_port = htons(8888); // 连接到服务器 iResult = connect(clientSocket, (SOCKADDR*)&serverAddress, sizeof(serverAddress)); if (iResult == SOCKET_ERROR) { printf("connect failed with error: %d\n", WSAGetLastError()); closesocket(clientSocket); WSACleanup(); return 1; } // 发送一条消息 const char* message = "Hello, server!"; iResult = send(clientSocket, message, strlen(message), 0); if (iResult == SOCKET_ERROR) { printf("send failed with error: %d\n", WSAGetLastError()); closesocket(clientSocket); WSACleanup(); return 1; } // 接收服务器的响应 char response[1024]; iResult = recv(clientSocket, response, sizeof(response), 0); if (iResult > 0) { response[iResult] = '\0'; printf("Server response: %s\n", response); } else if (iResult == 0) { printf("Connection closed by server.\n"); } else { printf("recv failed with error: %d\n", WSAGetLastError()); } // 关闭socket连接 closesocket(clientSocket); WSACleanup(); return 0; } ``` 需要注意的是,这里的服务器地址和端口号需要根据实际情况进行修改。同时,客户端需要先连接到服务器,然后再发送消息和接收响应。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值