在寫TCP應用的時候一般都通過Accept來接入連接的接入,但對於Socket來說這個Accept同時能處理多大的量一般都沒有明確說明,在應用中主要根據自己的需要設置Listen的隊列數量.那Listen(1000)是不是就能說明同時刻1000個連接進來都能被Accept到呢?通過測試的結果來看windows下是不能的....Linux下則可以.
測試代碼
- C#
Socket mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); mSocket.Bind(new IPEndPoint(IPAddress.Any,80)); mSocket.Listen(1000); int i = 0; while (true) { Socket http= mSocket.Accept(); System.Threading.Thread.Sleep(200); i++; Console.WriteLine("Accept:{0} ", i); } - win C++
iResult = listen(ListenSocket, 1000); if (iResult == SOCKET_ERROR) { printf("listen failed with error: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 1; } int i=0; while(true) { // Accept a client socket ClientSocket = accept(ListenSocket, NULL, NULL); i++; if (ClientSocket == INVALID_SOCKET) { printf("accept failed with error: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 1; } iResult = recv(ClientSocket, recvbuf, recvbuflen, 0); printf("accept: %d\n", i); } - linux c++
if (bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0) { perror("bind"); return 1; } listen(server_sockfd,1000); sin_size=sizeof(struct sockaddr_in); int i=0; while(1) { i++; if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<0) { cout<<"accept error"; return 1; } len=recv(client_sockfd,buf,BUFSIZ,0); cout << "Accept:" << i<<"Receive:"<<len; }
通過AB開啟500個用戶壓相應的程序,C#,WIN C++都會導致AB出現apr_socket_recv: Connection refused (111).但Linux c++這代碼是完全正常,AB所有請求的連接都通過被Linux c++接入.
以上程序上所有Listen都是1000, 按理500個用戶同時接入不應該存在被拒絕的情況,因為請求的連接數並沒達隊列溢出的情況.但測試的結果很明確地說明的問題所在,winsocket下無法同時接入這個量的連接,其實在測試過程250個用戶同時接入winsocket就存在拒絕接入的情況,當然服務是不會有影響只是有些連接無法被接入.
總結
通過測試可以確認是winsocket的限制,windows則沒有因為IIS是可以抵抗這么多用戶同時接入的.其實對於普通服務來說同時200個用戶接入已經是一個不小的量了,因為持續這個量的處理每秒接入量可以達到1-2W.但感覺奇怪的是為什么Listen(1000)在winsocket下沒有起到作用呢?找了很多資料都沒找到具體原因,如果有熟悉winsocket還有其他參數設置的話希望能分享一下...
