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

ICQ弱点检测代码

开发平台:

Visual C++

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