Linux----網路程式設計(I/O複用之select系統呼叫)
阿新 • • 發佈:2018-12-16
io_select_ser.c
1. #include <string.h> 2. #include <assert.h> 3. #include <unistd.h> 4. #include <stdio.h> 5. #include <stdlib.h> 6. #include <sys/socket.h> 7. #include <netinet/in.h> 8. #include <sys/time.h> 9. #include <sys/select.h> 10. 11. #define MAXFD 10 12. 13. //IO_select 14. void fds_init(int fds[]) 15. { 16. int i = 0; 17. for(; i<MAXFD; i++) 18. { 19. fds[i] = -1; 20. } 21. } 22. 23. void fds_add(int fds[], int fd) 24. { 25. int i = 0; 26. for(; i<MAXFD; i++) 27. { 28. if(fds[i] == -1) 29. { 30. fds[i] = fd; 31. return; 32. } 33. } 34. } 35. 36. void fds_del(int fds[], int fd) 37. { 38. int i = 0; 39. for(; i<MAXFD; i++) 40. { 41. if(fds[i] == fd) 42. { 43. fds[i] = -1; 44. return; 45. } 46. } 47. } 48. 49. int main() 50. { 51. int sockfd = socket(AF_INET, SOCK_STREAM, 0); 52. assert(sockfd != -1); 53. 54. struct sockadd_in saddr, caddr; 55. memset(&saddr, 0, sizeof(saddr)); 56. saddr.sin_family = AF_INET; 57. saddr.sin_port = htons(6000); 58. saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 59. 60. int res = bind(sockfd, (struct sockadd*)&saddr, sizeof(saddr)); 61. assert(res != -1); 62. 63. listen(sockfd, 5); 64. 65. int fds[MAXFD]; 66. fds_init(fds); 67. 68. fds_add(fds, sockfd); 69. 70. while(1) 71. { 72. fd_set fdset; 73. FD_ZERO(&fdset); 74. 75. int maxfd = -1; 76. int i = 0; 77. for(; i<MAXFD; i++) 78. { 79. if(fds[i] == -1) 80. { 81. continue; 82. } 83. FD_SET(fds[i], &fdset); 84. if(fds[i] > maxfd) 85. { 86. maxfd = fds[i];//替換到集合裡 87. } 88. } 89. struct timeval tv = {5,0};//超時時間為5s 90. 91. int n = select(maxfd+1, &fdset, NULL, NULL, &tv);//第一個引數描述符最大值+1,tv置為空,阻塞 92. if(n == -1) 93. { 94. printf("select error\n"); 95. continue; 96. } 97. else if(n == 0) 98. { 99. printf("time out\n"); 100. continue; 101. } 102. else 103. { 104. int i = 0; 105. for(; i<MAXFD; i++) 106. { 107. if(fds[i] == -1) 108. { 109. continue; 110. } 111. if(FD_ISSET(fds[i], &fdset)) //是否有資料 112. { 113. if(fds[i] == sockfd) 114. { 115. //accept特殊描述符 116. int len = sizeof(caddr); 117. int c = accept(sockfd, (struct sockaddr*)&caddr, &len); 118. if(c < 0) 119. { 120. continue; 121. } 122. printf("accept c = %d\n",c); 123. fds_add(fds, c); 124. } 125. else 126. { 127. //recv普通描述符 128. char buff[128] = {0}; 129. int num = recv(fds[i], buff, 127, 0); 130. if(num <= 0) 131. { 132. close(fds[i]); 133. fds_del(fds, fds[i]); 134. printf("one client over!\n"); 135. } 136. else 137. { 138. printf("recv(%d) = %s\n",fd[i], buff); 139. send(fds[i], "ok", 2, 0); 140. } 141. } 142. } 143. } 144. } 145. } 146. }
io_select_cli.c
1. #include <string.h> 2. #include <assert.h> 3. #include <unistd.h> 4. #include <stdio.h> 5. #include <stdlib.h> 6. #include <sys/socket.h> 7. #include <netinet/in.h> 8. #include <sys/select.h> 9. 10. //IO_select 11. int main() 12. { 13. int sockfd = socket(AF_INET, SOCK_STREAM, 0); 14. assert(sockfd != -1); 15. 16. struct sockadd_in saddr; 17. memset(&saddr, 0, sizeof(saddr)); 18. saddr.sin_family = AF_INET; 19. saddr.sin_port = htons(6000); 20. saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 21. 22. int res = bind(sockfd, (struct sockadd*)&saddr, sizeof(saddr)); 23. assert(res != -1); 24. 25. while(1) 26. { 27. char buff[128] = {0}; 28. printf("input:\n"); 29. fgets(buff, 128, stdin); 30. if(strncmp(buff,"end",3) == 0) 31. { 32. break; 33. } 34. send(sockfd, buff, strlen(buff), 0); 35. memset(buff, 0, 128); 36. recv(sockfd, buff, 127, 0); 37. printf("buff = %s\n",buff); 38. } 39. close(sockfd); 40. exit(0); 41. }
結果: