linux – 为什么总是连接5个没有程序的连接?
这个问题类似于
Network port open,but no process attached?和
netstat shows a listening port with no pid but lsof does not.但是它们的答案无法解决我的问题,因为它太奇怪了.
我有一个名为lps的服务器应用程序,它等待端口8588上的tcp连接. [root@centos63 lcms]# netstat -lnp | grep 8588 tcp 0 0 0.0.0.0:8588 0.0.0.0:* LISTEN 6971/lps 正如您所看到的,侦听套接字没有任何问题,但当我将数千个测试客户端(由另一位同事编写)连接到服务器时,无论是2000,3000还是4000.总有5个客户端(也是随机连接并向服务器发送登录请求,但无法接收任何响应.以3000个客户为例.这是netstat命令提供的内容: [root@centos63 lcms]# netstat -nap | grep 8588 | grep ES | wc -l 3000 这是lsof命令输出: [root@centos63 lcms]# lsof -i:8588 | grep ES | wc -l 2995 这5个连接在这里: [root@centos63 lcms]# netstat -nap | grep 8588 | grep -v 'lps' tcp 92660 0 192.168.0.235:8588 192.168.0.241:52658 ESTABLISHED - tcp 92660 0 192.168.0.235:8588 192.168.0.241:52692 ESTABLISHED - tcp 92660 0 192.168.0.235:8588 192.168.0.241:52719 ESTABLISHED - tcp 92660 0 192.168.0.235:8588 192.168.0.241:52721 ESTABLISHED - tcp 92660 0 192.168.0.235:8588 192.168.0.241:52705 ESTABLISHED - 上面的5显示它们在端口8588上连接到服务器但没有连接程序.并且第二列(即RECV-Q)随着客户端发送请求而不断增加. 上面的链接说明了NFS mount和RPC.至于RPC,我使用了命令rcpinfo -p,结果与端口8588无关.而NFS mount,nfssta输出显示错误:没有客户端统计信息(/ proc / net / rpc / nfs:没有这样的文件或目录) . 问题:这怎么可能发生?总是5,也不是来自同一个5个客户.我不认为这是端口冲突,因为其他客户端也连接到相同的服务器IP和端口,它们都由服务器正确处理. 注意:我正在使用Linux epoll来接受客户端请求.我还在我的程序中编写调试代码并记录接受返回但无法找到5个连接的每个套接字(以及客户端的信息).这是uname -a输出: Linux centos63 2.6.32-279.el6.x86_64 #1 SMP Fri Jun 22 12:19:21 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux 谢谢你的帮助!我真的很困惑. 更新2013-06-08: accept is called by a TCP server to return the next completed connection from the front of the completed connection queue. If the completed connection queue is empty,the process is put to sleep (assuming the default of a blocking socket). 因此,如果队列中仍有一些已完成的连接,为什么进程会进入休眠状态? 更新2013-7-1: 解决方法
我尝试使用以下参数复制您的问题:
>服务器使用epoll来管理连接. 我不能复制这个问题.这是我的服务器源代码. #include <stddef.h> #include <stdint.h> #include <stdbool.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/epoll.h> #include <err.h> #include <sysexits.h> #include <string.h> #include <unistd.h> struct { int numfds; int numevents; struct epoll_event *events; } connections = { 0,NULL }; static int create_srv_socket(const char *port) { int fd = -1; int rc; struct addrinfo *ai = NULL,hints; memset(&hints,sizeof(hints)); hints.ai_flags = AI_PASSIVE; if ((rc = getaddrinfo(NULL,port,&hints,&ai)) != 0) errx(EX_UNAVAILABLE,"Cannot create socket: %s",gai_strerror(rc)); if ((fd = socket(ai->ai_family,ai->ai_socktype,ai->ai_protocol)) < 0) err(EX_OSERR,"Cannot create socket"); if (bind(fd,ai->ai_addr,ai->ai_addrlen) < 0) err(EX_OSERR,"Cannot bind to socket"); rc = 1; if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&rc,sizeof(rc)) < 0) err(EX_OSERR,"Cannot setup socket options"); if (listen(fd,25) < 0) err(EX_OSERR,"Cannot setup listen length on socket"); return fd; } static int create_epoll(void) { int fd; if ((fd = epoll_create1(0)) < 0) err(EX_OSERR,"Cannot create epoll"); return fd; } static bool epoll_join(int epollfd,int fd,int events) { struct epoll_event ev; ev.events = events; ev.data.fd = fd; if ((connections.numfds+1) >= connections.numevents) { connections.numevents+=1024; connections.events = realloc(connections.events,sizeof(connections.events)*connections.numevents); if (!connections.events) err(EX_OSERR,"Cannot allocate memory for events list"); } if (epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&ev) < 0) { warn("Cannot add socket to epoll set"); return false; } connections.numfds++; return true; } static void epoll_leave(int epollfd,int fd) { if (epoll_ctl(epollfd,EPOLL_CTL_DEL,NULL) < 0) err(EX_OSERR,"Could not remove entry from epoll set"); connections.numfds--; } static void cleanup_old_events(void) { if ((connections.numevents - 1024) > connections.numfds) { connections.numevents -= 1024; connections.events = realloc(connections.events,sizeof(connections.events)*connections.numevents); } } static void disconnect(int fd) { shutdown(fd,SHUT_RDWR); close(fd); return; } static bool read_and_reply(int fd) { char buf[128]; int rc; memset(buf,sizeof(buf)); if ((rc = recv(fd,buf,sizeof(buf),0)) <= 0) { rc ? warn("Cannot read from socket") : 1; return false; } if (send(fd,rc,MSG_NOSIGNAL) < 0) { warn("Cannot send to socket"); return false; } return true; } int main() { int srv = create_srv_socket("8558"); int ep = create_epoll(); int rc = -1; struct epoll_event *ev = NULL; if (!epoll_join(ep,srv,EPOLLIN)) err(EX_OSERR,"Server cannot join epollfd"); while (1) { int i,cli; rc = epoll_wait(ep,connections.events,connections.numfds,-1); if (rc < 0 && errno == EINTR) continue; else if (rc < 0) err(EX_OSERR,"Cannot properly perform epoll wait"); for (i=0; i < rc; i++) { ev = &connections.events[i]; if (ev->data.fd != srv) { if (ev->events & EPOLLIN) { if (!read_and_reply(ev->data.fd)) { epoll_leave(ep,ev->data.fd); disconnect(ev->data.fd); } } if (ev->events & EPOLLERR || ev->events & EPOLLHUP) { if (ev->events & EPOLLERR) warn("Error in in fd: %d",ev->data.fd); else warn("Closing disconnected fd: %d",ev->data.fd); epoll_leave(ep,ev->data.fd); disconnect(ev->data.fd); } } else { if (ev->events & EPOLLIN) { if ((cli = accept(srv,NULL,0)) < 0) { warn("Could not add socket"); continue; } epoll_join(ep,cli,EPOLLIN); } if (ev->events & EPOLLERR || ev->events & EPOLLHUP) err(EX_OSERR,"Server FD has failed",ev->data.fd); } } cleanup_old_events(); } } 这是客户: from socket import * import time scks = list() for i in range(0,3000): s = socket(AF_INET,SOCK_STREAM) s.connect(("localhost",8558)) scks.append(s) time.sleep(600) 在本地计算机上运行时,我使用端口8558(1个侦听,3000个客户端插槽和3000个服务器端套接字)获得6001个套接字. $ss -ant | grep 8558 | wc -l 6001 检查客户端连接的IP连接数量时,我得到3000. # lsof -p$(pgrep python) | grep IPv4 | wc -l 3000 我也尝试在远程机器上使用服务器进行测试,但也取得了成功. 我建议你尝试做同样的事情. 另外,请尝试完全关闭iptables,以防它的某些连接跟踪怪癖. 编辑:我已经完成了另一项测试,它会产生您在旁边看到的输出.您的问题是您正在抢先关闭服务器端的连接. 我可以复制类似于您所看到的执行以下操作的结果: >将一些数据读入我的服务器后,调用shutdown(fd,SHUT_RD). 执行此操作后,可以看到以下行为. >在客户端,我使用ESTABLISHED在netstat / ss中打开3000个连接. 这只发生在半关闭连接上. 因此我怀疑这是您的客户端或服务器程序中的错误.您正在向服务器所对的服务器发送内容,或者服务器因某种原因无效关闭连接. 您需要确认“异常”连接的状态(如close_wait或其他). 在这个阶段,我也认为这是一个编程问题,而不是属于serverfault的东西.在没有看到客户端/服务器的源的相关部分的情况下,任何人都无法追踪故障原因.尽管我非常有信心这与操作系统处理连接的方式无关. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |