刚开始学习,难免有些疏漏之处,请各位多多指教。
程序亲测可以使用。废话不多说。
网络IO模型分为阻塞IO、非阻塞IO、异步IO、IO复用、信号驱动IO。
阻塞IO: 有数据时,直接读;没有数据时,等待读。
非阻塞IO: 无论内核有没有数据都读。
以下是程序:
1. serevr.c
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h> 5 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 #include <netinet/in.h> 9 #include <arpa/inet.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 13 14 15 #define PORT 4455 16 #define MAX_LEN 5 17 18 //1. 初始化socket - tcp 19 int init_socket() 20 { 21 //1-1. socket 22 int sfd = socket(AF_INET,SOCK_STREAM,0); 23 if(sfd == -1) 24 { 25 perror("socket"); 26 exit(1); 27 } 28 //1-2 REUSEADDR 29 int val = 1; 30 int ret = setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,(void *)&val,sizeof(val)); 31 if(ret == -1) 32 { 33 perror("setsockopt"); 34 exit(1); 35 } 36 // 1-3 bind 37 struct sockaddr_in saddr; 38 saddr.sin_family = AF_INET; 39 saddr.sin_addr.s_addr = INADDR_ANY; 40 saddr.sin_port = htons(PORT); 41 ret = bind(sfd,(struct sockaddr *)&saddr,sizeof(saddr)); 42 if(ret == -1) 43 { 44 perror("bind"); 45 exit(1); 46 } 47 // 1-4 listen 48 ret = listen(sfd,MAX_LEN); 49 if( ret == -1) 50 { 51 perror("listen"); 52 exit(1); 53 } 54 55 printf("Srever is ready ... "); 56 return sfd; 57 } 58 //2. 处理接收,设置为非阻塞型的 59 int deal_accept(int sfd) 60 { 61 // 2-1 accept 62 int cfd = accept(sfd,NULL,NULL); 63 if(cfd == -1) 64 { 65 perror("accept"); 66 exit(1); 67 } 68 // 2-2 获得cfd属性 69 int flags = fcntl(cfd,F_GETFL); 70 if(flags == -1) 71 { 72 perror("fcntl F_GETFL"); 73 exit(1); 74 } 75 // 2-2 判断flags是否具有O_NONBLOCK属性 76 if(!(flags&O_NONBLOCK)) 77 { 78 flags |= O_NONBLOCK; 79 int ret = fcntl(cfd,F_SETFL,flags); 80 if(ret == -1) 81 { 82 perror("fcntl F_SETFL"); 83 exit(1); 84 } 85 } 86 return cfd; 87 } 88 89 void deal_communication(int cfd) 90 { 91 char buf[64] = {'