为什么大量Socket并发请求时会有部分失败?? 求高手解答!!
现象:
同时启动2000个线程,每个线程都去访问同一个服务器(IP、端口相同)。
发现会有部分线程连接失败,错误码一般有下面两个:
①10048(Address already in use.)
②10061(Connection refused.)
另:不同的服务器出错的比率也不同,自己写的Java服务端出错的比率要比Apache的多(服务端只把客户端发来的字符串打印到屏幕上,然后继续接收下一个请求)。
问题:
为什么在很短的时间内有过多的网络连接请求时,会有部分连接失败?其根本原因是什么?(1024-5000内的端口还有剩余)
Java/C/C++、Windows/Linux都有同样的问题,所以应该是Socket或底层网络设备或驱动的问题,不过没找到权威的资料。
如能给几个参考文档也是极好的~
注:请不要回答如何规避这个问题的方法,公司要我调查出现这个问题的原因。调查好久了没找到答案、只好发帖求助了。
代码:
下面是客户端代码,服务端的很简单就不贴出来了,访问www.baidu.com 或本地Apache服务都是一样的问题。
// main 函数
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
// Win Socket初始化
// ...
// 创建2000个线程
HANDLE ths[2000] = {0};
for(int i=0; i<2000; i++) {
HANDLE hTh = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc,
(LPVOID)(i+1), CREATE_SUSPENDED, NULL);
if(NULL == hTh) {
printf("Create thread failed(%d:%d)\n", i, GetLastError());
return -1;
}
ths[i] = hTh;
}
printf("Create thread success.\n");
// 启动创建好的线程
for(int i=0; i<2000; i++) {
ResumeThread(g_th[i]);
}
Sleep(5000);
return nRetCode;
}
// 线程函数
DWORD ThreadProc(LPVOID lpParameter)
{
char ch[100] = {0};
int i = (int)lpParameter;
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
if (INVALID_SOCKET == sockClient) {
printf("socket error(%d:%d)\n", i, WSAGetLastError());
return 1;
}
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("localhost");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(80);
int err = connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
if(SOCKET_ERROR == err) {
// 会出现10048、10061两种类型的错误
printf("connect error(%d:%d)\n", i, WSAGetLastError());
return 1;
}
sprintf(ch, "GET /app/?a=%d HTTP/1.1", i);
err = send(sockClient, ch, strlen(ch)+1, 0);
if(SOCKET_ERROR == err) {
printf("send error(%d:%d)\n", i, WSAGetLastError());
return 1;
}
closesocket(sockClient);
printf("proc ok(%d)\n", i);
return 0;
}