最新消息:

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

C/C++ admin 3483浏览 0评论
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 9999n");
 
 
	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] closen",i);
			  close(fd[i]);
			  FD_CLR(fd[i],&fdsr);
			  fd[i]=0;
			  conn_amount--;
			}
			else//否则有相应的数据发送过来 ,进行相应的处理
			{
			  //buf[ret]=0;
			  printf("%dn",ret);
			  printf("client[%d] send:%sn",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 errorn");
				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:%dn",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 ,exitn");
				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);
}

转载请注明:爱开源 » 有用的代码小片段2-TCP,Socket,Select

您必须 登录 才能发表评论!