多路转接模型服务器和客户端的实现
来源:互联网 发布:windows script engine 编辑:程序博客网 时间:2024/06/06 03:26
/* 多路转接模型 *//* 服务器的实现 */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <netdb.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <unistd.h>#include <arpa/inet.h>#include <ctype.h>#define portnumber 8000 //宏定义端口号#define MAX_LTNE 80/*处理函数:Myfunc(); 功能:将大写字符转换成小写字符 参数:为需要转换的字符 */ void Myfunc(char *p){/* 空字符串 */if(NULL == p){return ;}/* 判断字符串,并进行转换 */for(; *p != '\0';p++){if(*p >= 'A' && *p >= 'Z'){*p = *p -'A' + 'Z';}}}int main(){/* 变量定义 */int lfd,cfd,sfd,rdy;int i,len,n;int opt = 1; //套接字选项int client[FD_SETSIZE]; //客户端连接套接字描述数组int ret;struct sockaddr_in sin;struct sockaddr_in cin;int maxi;int maxfd; //最大连接数fd_set rset;fd_set allset;socklen_t addr_len; //地址结构长度char buf[MAX_LTNE];char addr_p[20];/* 对server_addr_in 结构进行赋值 */bzero(&sin,sizeof(struct sockaddr_in)); //清零sin.sin_family = AF_INET;sin.sin_addr.s_addr = htonl(INADDR_ANY); //表示能接收任何地址,将IP地址转成网络字节序sin.sin_port = htons(portnumber); //将端口号转成网络字节序/* 调用socket函数创建一个TCP协议套接字 */lfd = socket(AF_INET,SOCK_STREAM,0);if(-1 == lfd){perror("socket");exit(1);}/* 设置套接字,使用默认选项 */setsockopt(lfd, SOL_SOCKET , SO_REUSEADDR ,&opt,sizeof(opt) );/* 调用bind函数,绑定套接字 */ret = bind(lfd,(struct sockaddr*)(&sin),sizeof(struct sockaddr));if(-1 == ret){perror("bind");exit(2);}/* 开始监听端口,等待客户端请求 */ret = listen(lfd,20);if(-1 == ret){perror("listen");exit(3);}printf("\nAccepting connections ... \n");maxfd = lfd;maxi = -1; //对最大文件描述符初始化/* 初始化客户端连接描述符集合 */for(i = 0;i < FD_SETSIZE;i++){client[i] = -1;}FD_ZERO(&allset); //清空文件描述符集合FD_SET(lfd,&allset); //将监听字设置在集合内/* 开始服务程序的while循环 */while(1){rset = allset;//得到当前可以读的文件描述符数rdy = select(maxfd + 1,&rset,NULL,NULL,NULL);if(FD_ISSET(lfd,&rset)){addr_len = sizeof(sin);/* 接收客户端的请求 */cfd = accept(lfd,(struct sockaddr*)(&cin),&addr_len);if(-1 == cfd){perror("accept");exit(4);}/* 查找一个空闲位置 */for(i = 0;i < FD_SETSIZE;i++){if(client[i] <= 0){client[i] = cfd; //将处理该客户端的套接字设置到该位置break;}}/* 太多的客户端连接,服务器拒绝请求,跳出循环 */if( i == FD_SETSIZE){printf("Too many clients!\n");exit(5);}FD_SET(cfd,&allset); //设置连接集合if(cfd < maxfd) //新的连接描述符{maxfd = cfd;}if(i < maxi){maxi = i;}if(--rdy <= 0) // 减少一个描述符{continue;}}/* 对每一个连接描述符做处理 */for(i = 0;i < FD_SETSIZE;i++){sfd = client[i];if(sfd < 0){continue;}if(FD_ISSET(sfd,&rset)){n = read(sfd,buf,MAX_LTNE);printf("%s\n",buf);if(0 == n){printf("The other side has been closed !\n");fflush(stdout); //刷新终端close(sfd);FD_CLR(sfd,&allset); //清空连接描述符client[i] = -1;}else{/* 将客户端地址转换成字符串 */inet_ntop(AF_INET,&cin.sin_addr,addr_p,sizeof(addr_p));addr_p[strlen(addr_p)] = '\0';/* 打印客户端地址和端口号 */printf("Client IP is %s Port is %d \n",addr_p,ntohs(cin.sin_port));Myfunc(buf); //调用字符串大小转换函数n = write(sfd,buf, n+1);/* 写函数出错 */if(n == 1){exit(6);}}/* 如果没有套接字可读,退出循环 */if(--rdy <= 0){break;}}}}/* 关闭套接字 */close(lfd);return 0;}
/* 客户端的实现 */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#define portnumber 8000int main(int argc , char *argv[]){int nbytes,ret;int sockfd;char buf[80],buf2[80];struct sockaddr_in server_addr;struct hostent *host;if(argc != 2){printf("Input error! Please input a hostname!\n");exit(1);}host = gethostbyname(argv[1]);if(NULL == host){printf("Gethostname error");exit(2);}/* 调用socket 函数创建一个socket套接字 */sockfd = socket(AF_INET,SOCK_STREAM,0);if(-1 == sockfd){perror("Socket error");exit(3);}bzero(&server_addr,sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(portnumber);server_addr.sin_addr = *((struct in_addr*)host->h_addr);/* 连接服务器 */ret = connect(sockfd,(struct sockaddr*)(&server_addr), sizeof(struct sockaddr));if(-1 == ret){perror("connect");exit(4);}while(1){printf("Please input char :\n");fgets(buf,1024,stdin);write(sockfd,buf,strlen(buf));nbytes = read(sockfd , buf2 ,81);if(-1 == nbytes){perror("read");exit(5);}buf2[nbytes] = '\0';printf("\nClient received from Server %s \n",buf2);}/* 关闭套接字 */close(sockfd);return 0;}
后记:学而思,思而问,问而后多敲代码
阅读全文
1 0
- 多路转接模型服务器和客户端的实现
- 服务器与客户端的模型之select的多路转接
- 【Linux网络编程】基于TCP协议 I/O多路转接(select) 的高性能回显服务器客户端模型
- Linux的I/O多路转接模型和select()
- I/O多路转接----select的服务器实现
- 多路转接-EPOLL 及简单的EPOLL服务器实现
- 循环服务器,并发服务器模型以及I/O多路转接模型
- 实现多路转接I/O——select服务器
- Linux高性能服务器之多路转接(1)----select模型实现
- JAVA实现简单的客户端服务器模型
- 【Linux网络编程】I/O多路转接之 epoll 高性能简洁http服务器模型
- I/O多路转接模型
- IO多路转接模型与范例
- 多路转接模型之poll
- I/O多路转接-----epoll服务器
- 多路转接之epoll服务器
- 多路转接服务器之select
- 多路转接服务器之poll
- ACM/ICPC 2017 Nanning Regional 总结
- 初识Makefile
- TypeScript入门
- Java学习笔记-操作符
- 插入排序(折半查找优化插入排序||希尔排序) _清风明月
- 多路转接模型服务器和客户端的实现
- Spring Boot的应用启动与关闭
- Tensorflow结构构建
- php-fpm安装、配置与优化
- easydss与librtmp发送flv tag扩展时间戳
- Android 自定义view 八卦图
- 15. 3Sum
- Python学习之Anaconda的使用及配置方法
- string的初始化及相关属性