Poll机制
来源:互联网 发布:2014年程序员考试真题 编辑:程序博客网 时间:2024/06/05 19:47
echo应答协议
echo会将输入的字符串送往标准输出。输出的字符串间以空白字符隔开,并在最后加上换行号。
echo server:功能是客户端向服务器发送消息,服务器接收输出并原样返回客户端。
Server
/************************************************************************* > File Name: poll.cpp > Author: > Mail: > Created Time: 2017年06月17日 星期六 14时28分03秒 ************************************************************************/#include<iostream>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<unistd.h>#include<stdio.h>#include<stdlib.h>#include<strings.h>#include<string.h>#include<errno.h>#include<sys/wait.h>#include<poll.h>#define IPADDRESS "127.0.0.1"#define PORT 6666#define MAXLINE 1024#define LISTENQ 5#define OPEN_MAX 1000#define INTTIM -1using namespace std;int bind_and_listen()//服务器端创建套接字,绑定,并监听,返回创建的套接字描述符,如果返回负值,表示有错误,具体见代码{ int serverfd;//服务器套接字,监听 struct sockaddr_in my_addr; unsigned int sin_size; if((serverfd=socket(AF_INET,SOCK_STREAM,0))==-1){ perror("scoket error!\n"); return -1; } printf("socket OK!\n"); my_addr.sin_family=AF_INET; my_addr.sin_port=htons(PORT);//这边端口号没有转化为主机字节序,导致客户端连不上。(忘了加htons) my_addr.sin_addr.s_addr=INADDR_ANY;//服务器地址配置 bzero(&(my_addr.sin_zero),0);//为啥把这个设置为0,需要查查??? if(bind(serverfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))==-1){ perror("bind error\n"); return -2; } printf("bind OK!\n"); if(listen(serverfd,LISTENQ)==-1){ printf("listen error\n"); return -3; } printf("listen ok!\n"); return serverfd;}void do_poll(int listenfd)//IO多路复用poll{ int connfd,sockfd; struct sockaddr_in clientaddr; socklen_t clientaddrlen=sizeof(clientaddr); struct pollfd clientfds[OPEN_MAX];//使用poll机制最大能够处理的事件个数,这里取名clientfds言外之意就是处理客户端个数 clientfds[0].fd=listenfd; clientfds[0].events=POLLIN;//clientfds[0]的事件属性events设置为可读 //其他的fd都初始化为-1 for(int i=1;i<OPEN_MAX;i++) clientfds[i].fd=-1; int ready_events_num=0; int events_num=1;//用于标记poll函数中第一个参数的元素个数 int max_index=0; while(1) { ready_events_num=poll(clientfds,max_index+1,INTTIM);//timeout为INTTIM(-1)表示无限等待,就是进程挂起,直到有事件发生。返回发生事件的个数,=0表示没有,大于0就是有,小于0(-1)表示出错。 if(ready_events_num==-1){ perror("poll error\n"); exit(1); } if(clientfds[0].revents&POLLIN)//先测试监听描述符(服务器描述符),接受新的连接 { if((connfd=accept(listenfd,(struct sockaddr*)&clientaddr,&clientaddrlen))==-1){ if(errno==EINTR)//请求的事件之前产生一个信号,调用可以重新发起 continue; else { perror("accept error\n"); exit(1); } } fprintf(stdout,"accept a new client: %s:%d\n",inet_ntoa(clientaddr.sin_addr),clientaddr.sin_port);//IP以点分十进制输出,以及端口号 int i; for(i=1;i<OPEN_MAX;i++) { if(clientfds[i].fd<0) { clientfds[i].fd=connfd;//客户端的描述符加入到clientfds中 break; } } if(i==OPEN_MAX){ fprintf(stderr,"too many clients.\n"); exit(1); } clientfds[i].events=POLLIN;//设置新添加的clientfds[i]为可读 max_index=(i>max_index)?i:max_index;//发生事件,最大的下标 if(ready_events_num<=1)//说明只有服务器描述符clientfds[0]有变化(接收新的客户端),其他无变化 continue; } char buff[MAXLINE];// memset(buff,0,MAXLINE); for(int i=1;i<=max_index;i++)//处理多个客户端发来的包 { if(clientfds[i].fd<0) continue; if(clientfds[i].revents&POLLIN)//客户端发来信息,服务器端有数据可读 { int len=read(clientfds[i].fd,buff,MAXLINE); if(len==0){//关闭连接,具体查查返回值的意义 close(clientfds[i].fd); clientfds[i].fd=-1; continue; } write(STDOUT_FILENO,buff,len);//写入STDOUT_FILEENO,不知道啥意思??? write(clientfds[i].fd,buff,len);//把buf信息发回去 } } }}int main(int argc,char **argv){ int listenfd=bind_and_listen(); if(listenfd<0) return 0; do_poll(listenfd); return 0;}
Client
/************************************************************************* > File Name: client.cpp > Author: > Mail: > Created Time: 2017年06月17日 星期六 15时49分43秒 ************************************************************************/#include<iostream>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<unistd.h>#include<stdio.h>#include<stdlib.h>#include<strings.h>#include<string.h>#include<errno.h>#include<sys/wait.h>#include<poll.h>#define IPADDRESS "127.0.0.1"#define PORT 6666#define MAXLINE 1024#define max(a,b) (a>b)?a:busing namespace std;static void handle_connection(int sockfd);int main(int argc,char**argv){ int connfd=0; int clen=0; struct sockaddr_in client; if(argc<2){ printf("Usage: client [server IP address]\n"); return -1; } client.sin_family=AF_INET; client.sin_port=htons(PORT);//转化为主机字节序 client.sin_addr.s_addr=inet_addr(argv[1]);//这个命名有问题,其实是服务器的地址 if((connfd=socket(AF_INET,SOCK_STREAM,0))==-1){ perror("socket error\n"); return -1; } int conres; if((conres=connect(connfd,(struct sockaddr*)&client,sizeof(client)))<0){ cout<<conres<<endl; perror("connect error\n"); return -1; } handle_connection(connfd); return 0;}static void handle_connection(int sockfd){ char sendline[MAXLINE],recvline[MAXLINE]; struct pollfd pfds[2]; pfds[0].fd=sockfd; pfds[0].events=POLLIN; pfds[1].fd=STDIN_FILENO;//把标准输入添加到描述符pfds[1]中 pfds[1].events=POLLIN; while(1) { poll(pfds,2,-1); if(pfds[0].revents&POLLIN) { int n=read(sockfd,recvline,MAXLINE);//读取服务器向客户端sockfd发来的信息 if(n==0){ fprintf(stderr,"client: server is closed.\n"); close(sockfd); } write(STDOUT_FILENO,recvline,n);//向标准输出写收到的信息 } if(pfds[1].revents&POLLIN)//测试标准输入是否准备好 { int n=read(STDIN_FILENO,sendline,MAXLINE); if(n==0){ shutdown(sockfd,SHUT_WR);//这个不太理解是啥意思 continue; } write(sockfd,sendline,n); } }}
makefile
all:server clientserver: server.o g++ -g -o server server.oclient: client.o g++ -g -o client client.oserver.o: server.cpp g++ -g -c server.cppclient.o:client.cpp g++ -g -c client.cppclean :all rm all
gdb传参数
#include<stdio.h> int main(int argc, char *argv[]) { int i; for(i = 0; i < argc; ++i) { printf("%s/n", argv[i]); } }
开始调试:
$gdb a.out
之后,在输入start之前:
使用命令设置main的参数,例如:
set args abc 123
这样 argv[1]就是”abc”
argv[2]是”123”
阅读全文
0 0
- Poll机制
- poll机制
- poll 机制
- poll机制
- Poll机制
- poll机制
- poll select 机制
- poll机制分析
- poll机制分析[转载]
- poll机制分析
- linux poll工作机制
- Linux poll机制分析
- poll机制分析
- Poll机制分析
- poll机制分析
- Linux poll机制
- Poll机制分析
- poll机制分析
- SDUT-1238 求数列的和
- 20170617Windows10_02_线程传参、时间片及线程启动退出
- Linux 设置apache,mysql开机启动
- GraphicsMagick+Lua
- 函数:定义一个函数,接收一个学生的分数数组,返回平均分
- Poll机制
- TextInput组件(绑定事件)
- CentOS7搭建FastDFS V5.11分布式文件系统及Java整合详细过程(二)
- 进口NFC,运放,时间数字转换 芯片替代
- tomcat性能调优
- centos 安装 redis3.0.0 集群
- Tomcat安装详细步骤
- 函数:输出某一个范围数字中的所有质数
- C白白的游戏服务器开发笔记:安装protobuf