Select服务器
来源:互联网 发布:淘宝网电脑端描述 编辑:程序博客网 时间:2024/05/17 07:09
select
#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<string.h>int array_fds[1024];static void Usage(const char *proc){ printf("Usage: %s [local_ip] [local_port]\n",proc);}int startup(char *_ip, int _port){ int sock = socket(AF_INET,SOCK_STREAM,0); if(sock < 0) { perror("sock"); exit(2); } int flag = 1; setsockopt(sock, SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag)); struct sockaddr_in local; local.sin_family = AF_INET; local.sin_port = htons(_port); local.sin_addr.s_addr = inet_addr(_ip); if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0) { perror("bind"); exit(3); } if(listen(sock,10)<0) { perror("listen"); exit(4); } return sock;}int main(int argc,char* argv[]){ if(argc != 3) { Usage(argv[0]); return 0; } int listenSock = startup(argv[1],atoi(argv[2])); int maxfd = 0; fd_set rfds; int array_size = sizeof(array_fds)/sizeof(array_fds[0]); array_fds[0] = listenSock; int i = 1; for(;i < array_size;i++) { array_fds[i] = -1; } while(1){ struct timeval _timeout = {0,0}; FD_ZERO(&rfds); maxfd = -1; for(i = 0;i<array_size;i++){ if(array_fds[i] > 0){ FD_SET(array_fds[i],&rfds); if(array_fds[i] > maxfd){ maxfd = array_fds[i]; } } } switch(select(maxfd+1,&rfds,NULL,NULL,NULL/*&_timeout*/)){ case 0: printf("timeout...\n"); break; case -1: perror("select"); break; default: { int j = 0; for(;j < array_size;j++){ if(array_fds[j]<0){ continue; } if(j == 0&&FD_ISSET(array_fds[j],&rfds)){ struct sockaddr_in client; socklen_t len = sizeof(client); int new_fd = accept(array_fds[j],\ (struct sockaddr*)&client,&len); if(new_fd < 0){ perror("accept"); continue; } else{ printf("get a new client: (%s:%d)\n",\ inet_ntoa(client.sin_addr),\ ntohs(client.sin_port)); int k = 1; for(;k < array_size;k++){ if(array_fds[k] < 0){ array_fds[k] = new_fd; break; } } if(k == array_size){ close(new_fd); } } } else if(j != 0&&\ FD_ISSET(array_fds[j],&rfds)) { char buf[10240]; ssize_t s = read(array_fds[j],buf,sizeof(buf)-1); if(s>0) { buf[s] = 0; printf("client say: %s\n",buf); } else if(s == 0) { printf("client quit!\n"); close(array_fds[j]); array_fds[j] = -1; } else { perror("read"); close(array_fds[j]); array_fds[j] = -1; } } else { } } } break; } } return 0;}
client
#include<stdio.h> #include<sys/types.h> #include<netinet/in.h> #include<arpa/inet.h> #include<sys/socket.h> #include<stdlib.h> #include<string.h> #include<strings.h> #include<sys/stat.h> #include<unistd.h> static void Usage(char * proc) { printf("Usage : %s [ip] [port]\n"); } int main(int argc, char* argv[]) { if(argc != 3) { Usage(argv[0]); return 1; } int sock = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in peer; peer.sin_family = AF_INET; peer.sin_port = htons(atoi(argv[2])); peer.sin_addr.s_addr = inet_addr(argv[1]); if(connect(sock, (struct sockaddr*)&peer, sizeof(peer)) < 0) { perror("connect"); return 2; } char buf[10240]; //int sfd = dup(STDOUT_FILENO); while(1) { printf("Please Enter : "); fflush(stdout); ssize_t s = read(0, buf, sizeof(buf)-1); int sfd = dup(STDOUT_FILENO); if(s > 0) { buf[s-1] = 0; //write(sock, buf, strlen(buf)); //输出重定向 //close(1); // int new_fd = dup(sock); int new_fd = dup2(sock, 1); if(new_fd == -1) { perror("dup()"); return -1; } printf("%s",buf); fflush(stdout); //恢复stdout dup2(sfd, STDOUT_FILENO); ssize_t _s = read(sock, buf, sizeof(buf)-1); if(_s > 0) { buf[_s] = 0; printf("sever # %s \n", buf); } } } close(sock); return 0; }
总结select服务器优缺点,与多进程/多线程服务器进行对比:
使用select注意事项:
1.要将sock_fd加入到maxfd+1中,要不就无法检测到网络连接,会一直阻塞在select语句
2.通过存储每次连接的描述符,设置FD_SET函数,在遍历的去判断FD_ISSET处理。
3.我们可以看到select每次有数据到来时,需要遍历的去寻找所有可用的描述符,来判断其是否满足处理的条件。
4.select的通知机制,轮询的去查看是否在maxfd+1内有满足条件的描述符
select优缺点:
与多进程/多线程服务器进行对比 它的优点在于:
1、不需要建立多个线程、进程就可以实现一对多的通信。
2、可以同时等待多个文件描述符,效率比起多进程多线程来说要高很多。
3、select()的可移植性更好,在某些Unix系统上不支持poll()
4、select() 对于超时值提供了更好的精度:微秒,而poll是毫秒
与多进程/多线程服务器进行对比 它的缺点在于:
1、每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大 ,循环次数有点多;
2、同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大 。
3、select支持的文件描述符数量太小了,默认是1024;
阅读全文
0 0
- Select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- select服务器
- Select服务器
- select服务器
- select多路单线程服务器
- select模型服务器代码
- python 服务器 select 游戏
- tcp服务器(使用select)
- MPLS IP VPN 跨域配置Option A及总结
- CSDN 积分的作用
- ptrace和wait的理解 (ptrace监控进程)
- Cesium开发实践(二)模拟多架飞机飞行
- gnuplot画图
- Select服务器
- LeetCode Two Sum 之 JavaScript 多种解法
- set中常用的方法
- Java基本数据类型
- 【leveldb】Leveldb实现原理分析(上)
- Spark源码分析-worker
- 手机验证码接收注册新账户
- 链表排序-LintCode
- Redux介绍