multiclient(recv_PEEK).c
上传用户:gzxinfenfa
上传日期:2015-02-06
资源大小:279k
文件大小:4k
源码类别:

ICQ弱点检测代码

开发平台:

Visual C++

  1. /* 模拟多个客户
  2.  * case 1: 两个socket顺序读写
  3.  * case 2: 使用I/O 复用技术完成两个socket读写
  4.  *         使用RECV判断客户端连接是否关闭
  5.  */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <sys/socket.h>
  10. #include <netinet/in.h>
  11. #include <errno.h>
  12. #include <netdb.h>
  13. #include <arpa/inet.h>
  14. #include <unistd.h>
  15. #include <sys/time.h>
  16. #include <sys/select.h>
  17. #define MAXDATASIZE 128
  18. #define max(a,b) ((a)>(b)?(a):(b))
  19. int main(int argc,char **argv){
  20. int sockfd1,sockfd2,nbytes;
  21. char buf[MAXDATASIZE];
  22. struct sockaddr_in srvaddr1,srvaddr2;
  23. int port1, port2;
  24. int isMultiplex = 0;
  25. if(argc<3){
  26. printf("usage:%s port1 port2n");
  27. exit(0);
  28. }
  29. //指定服务器地址
  30. port1=atoi(argv[1]);
  31. bzero(&srvaddr1,sizeof(srvaddr1));
  32. srvaddr1.sin_family = AF_INET;
  33. srvaddr1.sin_port = htons(port1);
  34. if(get_ip("127.0.0.1",&srvaddr1.sin_addr)==-1){
  35. perror(strerror(errno));
  36. exit(1);
  37. }
  38. port2=atoi(argv[2]);
  39. bzero(&srvaddr2,sizeof(srvaddr2));
  40. srvaddr2.sin_family = AF_INET;
  41. srvaddr2.sin_port = htons(port2);
  42. if(get_ip("localhost",&srvaddr2.sin_addr)==-1){
  43. perror(strerror(errno));
  44. exit(1);
  45. }
  46. if(argc==4) isMultiplex=1;
  47. //1.创建网络端点
  48. sockfd1 = socket(AF_INET,SOCK_STREAM,0);
  49. sockfd2 = socket(AF_INET,SOCK_STREAM,0);
  50. if(sockfd1 == -1 || sockfd2 == -1){
  51. printf("create socket errorn");
  52. exit(1);
  53. }
  54. //2.连接服务器
  55. if( connect(sockfd1,(struct sockaddr *)&srvaddr1,sizeof(struct sockaddr))==-1 ||
  56. connect(sockfd2,(struct sockaddr *)&srvaddr2,sizeof(struct sockaddr))==-1){
  57. printf("connect errorn");
  58. exit(1);
  59. }
  60. //3.发送请求
  61. write(sockfd1, "Hello-1", 7);
  62. write(sockfd2, "Hello-2", 7);
  63. //4.接收响应
  64. struct timeval starttime,endtime;
  65. gettimeofday(&starttime,NULL); // get Now time
  66. printf("start time:%ld ",starttime.tv_sec);
  67. if(isMultiplex == 0){
  68. printf("  -- Sequence mode.n");
  69. if((nbytes=read(sockfd1,buf,MAXDATASIZE))==-1){
  70. printf("read errorn");
  71. exit(1);
  72. }
  73. buf[nbytes]='';
  74. gettimeofday(&endtime,NULL);
  75. printf("(%ld) server1 respons:%sn",endtime.tv_sec,buf);
  76. if((nbytes=read(sockfd2,buf,MAXDATASIZE))==-1){
  77. printf("read errorn");
  78. exit(1);
  79. }
  80. buf[nbytes]='';
  81. gettimeofday(&endtime,NULL);
  82. printf("(%ld) server2 respons:%sn",endtime.tv_sec,buf);
  83. }
  84. else{ // I/O 多路复用
  85. int fd1_finished=0;
  86. int fd2_finished=0;
  87. int maxfd ;
  88. fd_set rdset;
  89. struct timeval tv;
  90. printf("  -- I/O multiplex mode.n");
  91. while(fd1_finished == 0 || fd2_finished == 0){
  92. FD_ZERO(&rdset);
  93. maxfd = -1;
  94. if(fd1_finished == 0) {
  95. FD_SET(sockfd1,&rdset);
  96. maxfd = sockfd1;
  97. }
  98. if(fd2_finished == 0){
  99. FD_SET(sockfd2,&rdset);
  100. if( maxfd < 0 ) maxfd = sockfd2;
  101. else
  102. maxfd = max(sockfd1, sockfd2);
  103. }
  104. tv.tv_sec=0;
  105. tv.tv_usec=100;
  106. int n=select(maxfd+1,&rdset,NULL,NULL,&tv);
  107. if(n<=0)
  108. continue;
  109. else{
  110. if( (0 == fd1_finished) && FD_ISSET(sockfd1,&rdset)){
  111. if( recv(sockfd1, buf, 1, MSG_PEEK) == 0 ){
  112. fd1_finished=1;
  113. }
  114. else {
  115. if((nbytes=read(sockfd1,buf,MAXDATASIZE))==-1){
  116. printf("read errorn");
  117. exit(1);
  118. }
  119. buf[nbytes]='';
  120. gettimeofday(&endtime,NULL);
  121. printf("(%ld) server1 respons:%sn",endtime.tv_sec,buf);
  122.     }
  123. }
  124. if( (0 == fd2_finished) && FD_ISSET(sockfd2,&rdset)){
  125. if( recv(sockfd2, buf, 1, MSG_PEEK) == 0 ){
  126. fd2_finished=1;
  127. }
  128. else {
  129. if((nbytes=read(sockfd2,buf,MAXDATASIZE))==-1){
  130. printf("read errorn");
  131. exit(1);
  132. }
  133. buf[nbytes]='';
  134. gettimeofday(&endtime,NULL);
  135. printf("(%ld) server2 respons:%sn",endtime.tv_sec,buf);
  136. }
  137. }
  138. }
  139. }
  140. }
  141. //关闭socket
  142. close(sockfd1);
  143. close(sockfd2);
  144. return 0;
  145. }
  146. //将字符串形式的IP地址转换为网络字节顺序的二进制形式
  147. //或根据主机名得到其第一个网络字节顺序的二进制形式
  148. int get_ip(char *address,struct in_addr *inaddr){
  149. struct hostent *he;
  150. if(inet_aton(address,inaddr)!=0){
  151. return 0;
  152. }
  153. he = gethostbyname(address);
  154. if(he!=NULL){
  155. *inaddr = *((struct in_addr *)(he->h_addr_list[0]));
  156. return 0;
  157. }
  158. return -1;
  159. }