这几天在看linux下关于网络通信的知识,相当于做点笔记。
这里给出了一个利用多线程的机制来处理的例子。先看代码,再来分析实现的原理。干货如下:
#include<sys/types.h> #include<sys/socket.h> #include<stdio.h> #include<netinet/in.h> #include<signal.h> #include<unistd.h> int main() { int server_sockfd,client_sockfd; int server_len,client_len; struct sockaddr_in server_addr; struct sockaddr_in client_addr; server_sockfd = socket(AF_INET, SOCK_STREAM, 0); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(9734); server_len = sizeof(server_addr); bind(server_sockfd,(struct sockaddr *)&server_addr,server_len); listen(server_sockfd,5); signal(SIGCHLD,SIG_IGN);//忽略僵尸进程 while(1){ char ch; printf("server waiting!\n"); client_len = sizeof(client_addr); client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_addr, &client_len); if(fork()==0) { read(client_sockfd,&ch,1); sleep(5); ch++; write(client_sockfd,&ch,1); close(client_sockfd); exit(0); } else { close(client_sockfd); } } }
这里先看看操作步骤:
1、创建客户端的套接字,server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
2、服务器端地址填充。
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY代表0.0.0.0,实际就是任意地址
server_addr.sin_port = htons(9734);//指定端口号
server_len = sizeof(server_addr);
3、端口绑定。bind(server_sockfd,(struct sockaddr *)&server_addr,server_len);
4、监听端口。listen(server_sockfd,5);
5、等待客户端请求。client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_addr,&client_len);
6、创建一个子进程来处理该请求。 if(fork()==0)
7、处理,并休眠5s。
8、关闭客户端,继续等待新请求。
再从头开来,服务器端实际是在进行一个轮回查询的工作,就是休眠5s来看看有没有客户端请求,休眠的5s是不处理任何请求的。也就是5s才响应一次请求,假如你春节买票刷票,对不起,5s刷一次才有效,否则都是徒劳,刷再多次还是在睡觉。
假设客户端有个请求在刚开始休眠就请求进来了,这必然导致一个问题,就是要缓冲5s,这个在很多时候用户是不能忍受的,而且这样的设计处理多客户请求也没有充分利用网络带宽,带宽本可以响应很大的数据量,但是服务器自己做死。所以这种处理方式是一个很low的设计。
下一节将讲解关于其他方式处理多客户请求的设计。