在一般系统上, 进程打开的句柄数目是1024, 但在有的系统上, 却不是这个数, 举个栗子:

yyyyyy$ ulimit -n
100001
       下面,我们来看看程序:

#include <unistd.h>  
#include <sys/types.h>  
#include <sys/socket.h>  
#include <netdb.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <ctype.h>  
#include <errno.h>  
#include <malloc.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  
#include <sys/ioctl.h>  
#include <stdarg.h>  
#include <fcntl.h>  
#include <fcntl.h>  

void fun(unsigned int n)
{
	struct timeval tv;              // 超时时间
	tv.tv_sec = 3;
    tv.tv_usec = 500;               // 注意单位是微秒

    fd_set rdfds;
    FD_ZERO(&rdfds);                // 描述集初始化
	
	int iSock = 0;
	for(unsigned int i = 0; i < n; i++)
	{
		iSock = socket(AF_INET, SOCK_DGRAM, 0);   // 让句柄泄漏
		printf("iSock is %d\n", iSock);
	}

	if(iSock >= 0)
	{
		iSock = socket(AF_INET, SOCK_DGRAM, 0);
		printf("iSock here is %d\n", iSock);
		FD_SET(iSock, &rdfds);
		printf("to select\n");
		select(iSock + 1, &rdfds, NULL, NULL, &tv);
	}
}

int main(int argc, char *argv[])
{
	unsigned int n = 2000;  
	fun(n);

	printf("main end\n");
	return 0;
}
        这个程序在一些系统上会core dump,  我们来用strace运行一下, 部分信息如下:

write(1, "iSock here is 2003\n", 19iSock here is 2003
)    = 19
write(1, "to select\n", 10to select
)             = 10
*** buffer overflow detected ***: strace terminated
======= Backtrace: =========
/lib64/libc.so.6(__fortify_fail+0x37)[0x7f50f3e81057]
/lib64/libc.so.6(+0x10d210)[0x7f50f3e7f210]
/lib64/libc.so.6(+0x10efc7)[0x7f50f3e80fc7]
strace[0x4040a1]
strace[0x416cfe]
strace[0x402706]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f50f3d93b35]
strace[0x402929]
======= Memory map: ========
00400000-00469000 r-xp 00000000 fd:01 535074                             /usr/bin/strace
00668000-00669000 r--p 00068000 fd:01 535074                             /usr/bin/strace
00669000-0066a000 rw-p 00069000 fd:01 535074                             /usr/bin/strace
0066a000-0066b000 rw-p 00000000 00:00 0 
00fdb000-00ffc000 rw-p 00000000 00:00 0                                  [heap]
7f50f3958000-7f50f396d000 r-xp 00000000 fd:01 8622                       /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f50f396d000-7f50f3b6c000 ---p 00015000 fd:01 8622                       /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f50f3b6c000-7f50f3b6d000 r--p 00014000 fd:01 8622                       /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f50f3b6d000-7f50f3b6e000 rw-p 00015000 fd:01 8622                       /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f50f3b6e000-7f50f3b70000 r-xp 00000000 fd:01 1794                       /usr/lib64/libdl-2.17.so
7f50f3b70000-7f50f3d70000 ---p 00002000 fd:01 1794                       /usr/lib64/libdl-2.17.so
7f50f3d70000-7f50f3d71000 r--p 00002000 fd:01 1794                       /usr/lib64/libdl-2.17.so
7f50f3d71000-7f50f3d72000 rw-p 00003000 fd:01 1794                       /usr/lib64/libdl-2.17.so
7f50f3d72000-7f50f3f2a000 r-xp 00000000 fd:01 1788                       /usr/lib64/libc-2.17.so
7f50f3f2a000-7f50f4129000 ---p 001b8000 fd:01 1788                       /usr/lib64/libc-2.17.so
7f50f4129000-7f50f412d000 r--p 001b7000 fd:01 1788                       /usr/lib64/libc-2.17.so
7f50f412d000-7f50f412f000 rw-p 001bb000 fd:01 1788                       /usr/lib64/libc-2.17.so
7f50f412f000-7f50f4134000 rw-p 00000000 00:00 0 
7f50f4134000-7f50f4154000 r-xp 00000000 fd:01 1780                       /usr/lib64/ld-2.17.so
7f50f4237000-7f50f4239000 rw-p 00000000 00:00 0 
7f50f424a000-7f50f424b000 rw-p 00000000 00:00 0 
7f50f424b000-7f50f424e000 r-xp 00000000 fd:01 1708                       /usr/lib64/libonion_security.so.1.0.19
7f50f424e000-7f50f434e000 ---p 00003000 fd:01 1708                       /usr/lib64/libonion_security.so.1.0.19
7f50f434e000-7f50f434f000 rw-p 00003000 fd:01 1708                       /usr/lib64/libonion_security.so.1.0.19
7f50f434f000-7f50f4353000 rw-p 00000000 00:00 0 
7f50f4353000-7f50f4354000 r--p 0001f000 fd:01 1780                       /usr/lib64/ld-2.17.so
7f50f4354000-7f50f4355000 rw-p 00020000 fd:01 1780                       /usr/lib64/ld-2.17.so
7f50f4355000-7f50f4356000 rw-p 00000000 00:00 0 
7ffc4b773000-7ffc4b794000 rw-p 00000000 00:00 0                          [stack]
7ffc4b7c4000-7ffc4b7c6000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
select(2004, [Aborted (core dumped)
       可见, 在select处core dump了, 所以, 用linux select的时候, 要特别小心, 尤其是在server端, 虽然这种场景不经常发生, 但一旦发生, 就非常难定位。

       我个人建议, 在server端, 尽量不要用select,  在client端, 能不用就不用吧!





本文转载:CSDN博客