Linux C服务端同时与多个客户端进行通讯大多是用多线程实现(网上有现成的,^_^),还有就是用select函数,找了基本思路-_-。
小花了一天,理清、搞定o(∩_∩)o...哈哈。
关键词:
select、fd_set rfds(文件描述符集)
l 服务端
服务端麻烦,解决的关键,用select探测每个文件描述符,有发生变化,则执行相应的代码
1. 创建socket;
2. my_addr.sin_family = AF_INET; /*sin_family is unsigned short, host byte order*/
my_addr.sin_port = htons(SERVERPORT);/*unsigned short, network byte order*/
my_addr.sin_addr.s_addr = INADDR_ANY;//inet_addr(INADDR_ANY); /*auto-fill with my IP*/
bzero(&(my_addr.sin_zero), 8); /*zero the rest of the struct*/
3. bind;
4. listen;
5. /* 把集合清空 */(这个是重点,每一次while循环都应清空fd_set集合,再把相应的句柄加入fd_set)
FD_ZERO(&rfds);
/* 把标准输入句柄0加入到集合中 */
FD_SET(0, &rfds);
maxfd = 0;
/* 把sockfd句柄加入到集合中 */
FD_SET(sockfd, &rfds);
if(sockfd > maxfd)
maxfd = sockfd;
/*把clientfd加入到rfds集合中*/
for(j = 0; j < currentid; j++)
{
FD_SET(clientfd[j], &rfds);
if(clientfd[j] > maxfd)
{
maxfd = clientfd[j];
}
}
6. /* 开始等待 */
retval = select(maxfd + 1, &rfds, NULL, NULL, &tv);
7. for(j = 0; j < currentid; j++)//遍历每个已经客户端
8. if(FD_ISSET(sockfd, &rfds))//判断select探测的sockfd描述符是否发生变化,若是变化则,clientfd[currentid] = accept(sockfd, (struct sockaddr *)&clientaddr, &sin_size );
9. if(FD_ISSET(clientfd[j], &rfds))判断select探测的clientid描述符是否发生变化;
l 客户端
客户端相对简单些,关键步骤:
1. Socket;
2. serv_addr.sin_family = AF_INET; /*host byte order*/
serv_addr.sin_port = htons(PORT); /*short,network byte order*/
serv_addr.sin_addr = *((struct in_addr *)server_host_name->h_addr);
bzero(&(serv_addr.sin_zero), 8);
3. connect;
4. /* 把集合清空 */
FD_ZERO(&rfds);
/* 把标准输入句柄0加入到集合中 */
FD_SET(0, &rfds);
maxfd = 0;
/* 把当前连接句柄sockfd加入到集合中 */
FD_SET(sockfd, &rfds);
if (sockfd > maxfd)
maxfd = sockfd;
5. /* 开始等待 */
retval = select(maxfd + 1, &rfds, NULL, NULL, &tv);
6. if (FD_ISSET(sockfd, &rfds))、if (FD_ISSET(0, &rfds))//每一个while循环,都判断是否有消息发送过来、或者是有消息发送出去