select并发求解
- C/C++ code
socket(…);bind(…);listen(…);while(1){accept(…);if(fork(..)==0){while(1)//????{read(…);process(…);write(…);}close(…);exit(…);}close(…);}这个程序,实现并发,不考虑其负载问题
1.问题:想问下这个里面的while是什么意思呢,如果不加while是不是读写一次数据就结束了连接呢?
一般用户访问服务器,是读写一次就关闭连接么,还是要用while一直保存着呢?
=================================分割
2.用select来监听描述符集,用数组保存来实现多路复用,在有数据时循环遍历数组
问题:此时若不用多线程则未实现并发?
对数组里面保存的描述符集,是遍历一次就需要清空掉么?还是一直保存着等待被动关闭呢?
3.问题:长连接(持久保存?)和短连接(连接后处理一次即关闭?)分别有什么比较典型的案例么?
4.如果多个用户同时请求,还是必须有先后?服务端怎样处理呢?
5.超过backlog个用户同时请求服务,怎么处理呢?让对方等待?那客户端(例如浏览器)会显示什么呢?
[解决办法]
楼主先去学习学习《UNIX网络编程》这本书吧。。可能对你大有裨益。
这里给个样例
- C/C++ code
int main(){ int listenfd,connfd; pid_t pid; struct sockaddr_in server; struct sockaddr_in client; int len; if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1) { perror("Creating socket failed"); exit(1); } int opt=SO_REUSEADDR; setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); bzero(&server,sizeof(server)); server.sin_family=AF_INET; server.sin_port=htons(PORT); server.sin_addr.s_addr=htonl(INADDR_ANY); if(bind(listenfd,(struct sockaddr *)&server,sizeof(server))==-1) { perror("Bind() failed"); exit(1); } if(listen(listenfd,BACKLOG)==-1) { perror("listen failed"); exit(1); } len=sizeof(client); while(1) { if((connfd=accept(listenfd,(struct sockaddr *)&client,(socklen_t *)&len))==-1) { perror("accept() failed"); exit(1); } if((pid=fork())>0) { close(connfd); continue; } else if(pid==0) { close(listenfd); process_cli(connfd,client); exit(0); } else { printf("fork() failed"); exit(0); } } close(listenfd); return 0;}
[解决办法]
while(1)处是一个进程的问题了。当其有连接的时候,即accept后,产生一个新的进程来对其读写操作。fork是一个产生进程的函数,返回值为0的表示是子进程。
- C/C++ code
if(fork(..)==0){while(1)//????{read(…);process(…);write(…);}close(…);exit(…);}
[解决办法]
根据以前的一点记忆,简单回答下,供参考
1、在服务器端的Socket分为两种,一种是监听socket,一种是实际与客户端进行连接,数据传输的socket
2、监听socket是一直存在的,用于随时接收客户端的申请
3、实际数据传输的socket是在接收到客户端的连接请求后,服务器端调用accept函数时,会再创建一个socket,这个socket创建之后,它去跟客户端建立连接,进行通信
4、服务器端能创建多少个用于数据通信的socket,就表示这个服务器端能同时支持多少个连接
[解决办法]
UNIX环境高级编程+UNIX网络编程卷1,2,看完可以毕业。