IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    有用的代码小片段2-TCP,Socket,Select

    Qiang发表于 2010-11-19 06:00:22
    love 0
    ?View Code C
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    
    #define MAXCONN 5 //连接队列中的个数
    int main()
    {
     
    	int fd[MAXCONN]={0}; //连接的fd
    	int conn_amount; //当前的连接数
    	int sock_fd,new_fd; //监听套接字 连接套接字
    	fd_set fdsr; //文件描述符集的定义
    	int maxsock;
    	struct timeval tv;
    	struct sockaddr_in server_addr; // 服务器的地址信息
    	struct sockaddr_in client_addr; //客户端的地址信息
    	socklen_t sin_size;
    	int ret,i;
    	char buf[256]={0};
     
    	memset(&server_addr,0,sizeof(server_addr));
    	server_addr.sin_family = AF_INET; 
    	server_addr.sin_port = htons(9999);
    	server_addr.sin_addr.s_addr = INADDR_ANY;//通配IP
     
    	//建立sock_fd套接字
    	if((sock_fd = socket(AF_INET,SOCK_STREAM,0))==-1)
    	{
    	  perror("setsockopt");
    	  exit(1);
    	}
     
     
    	if(bind(sock_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) == -1)
    	{
    	  perror("bind error!\n");
    	  exit(1);
    	}
     
    	if(listen(sock_fd,MAXCONN)==-1)
    	{
    	  perror("listen error!\n");
    	  exit(1);
    	}
    	printf("listen port 9999\n");
     
     
    	conn_amount =0;
    	sin_size = sizeof(client_addr);
    	maxsock = sock_fd;
     
    	while(1)
    	{
     
    		//初始化文件描述符集合
    		FD_ZERO(&fdsr); //清除描述符集
    		FD_SET(sock_fd,&fdsr); //把sock_fd加入描述符集
     
    		//超时的设定
    		tv.tv_sec = 30;
    		tv.tv_usec =0;
     
    		//添加活动的连接
    		for(i=0;i<MAXCONN;i++) 
    		{
    		  if(fd[i]!=0)
    		  {
    			  FD_SET(fd[i],&fdsr);
    		  }
    		}
     
    		//如果文件描述符中有连接请求会做相应的处理,实现I/O的复用 多用户的连接通讯
    		ret = select(maxsock +1,&fdsr,NULL,NULL,&tv);
    		if(ret < 0) //没有找到有效的连接 失败
    		{
    		  perror("select error!\n");
    		  break;
    		}
    		else if(ret == 0)// 指定的时间到,
    		{
    		  printf("timeout \n");
    		  continue;
    		}
     
    		//循环判断有效的连接是否有数据到达
    		for(i=0;i<conn_amount;i++)
    		{
    		  if(FD_ISSET(fd[i],&fdsr))
    		  {
    			memset(buf,0,256);
    			ret = recv(fd[i],buf,sizeof(buf),0);
    			if(ret <=0) //客户端连接关闭,清除文件描述符集中的相应的位
     
    			{
    			  printf("client[%d] close\n",i);
    			  close(fd[i]);
    			  FD_CLR(fd[i],&fdsr);
    			  fd[i]=0;
    			  conn_amount--;
    			}
    			else//否则有相应的数据发送过来 ,进行相应的处理
    			{
    			  //buf[ret]=0;
    			  printf("%d\n",ret);
    			  printf("client[%d] send:%s\n",i,buf);
    			  send(fd[i],buf,sizeof(buf),0);
    			}
    		  }
    		}//for
     
    		if(FD_ISSET(sock_fd,&fdsr))
    		{
    			new_fd = accept(sock_fd,(struct sockaddr *)&client_addr,&sin_size);
    			if(new_fd <=0)
    			{
    				perror("accept error\n");
    				continue;
    			}
    			//添加新的fd 到数组中 判断有效的连接数是否小于最大的连接数,如果小于的话,就把新的连接套接字加入集合
    			if(conn_amount <MAXCONN)
    			{
    				for(i=0;i< MAXCONN;i++)
    				{
    					if(fd[i]==0)
    					{
    						fd[i] = new_fd;
    						break;
    					}
    				}
    				conn_amount++;
    				printf("new connection client[%d] %s:%d\n",conn_amount,inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
    				if(new_fd > maxsock)
    				{
    					maxsock = new_fd;
    				}
    			}
    			else
    			{
    				printf("max connections arrive ,exit\n");
    				send(new_fd,"bye",4,0);
    				close(new_fd);
    				continue;
    			}
    		}
    	}//while
     
     
    	for(i=0;i<MAXCONN;i++)
        {
    		if(fd[i]!=0)
    		{
    			close(fd[i]);
            }
        }
     
        exit(0);
    }


沪ICP备19023445号-2号
友情链接