linux socket接收、发送小工具(支持tcp、udp包(组播)的发送接收)

最近项目中大量使用socket,代码测试时需要模拟各种输入,因此写了个小程序模拟socket输入。因为经常需要测试组播数据,所以加进了udp组播的发送和接收。

主要功能:

(1)支持发送、接收tcp数据;

(2)支持发送、接收udp(以及组播)数据;

(3)支持文件输入、输出;

(4)支持反复、定时发送;

(5)通过不同选项,同一程序既可作为发送端,也可作为接收端。

更多详细选项,请看程序说明。

 

代码如下:

 1  #include  < stdio.h >
 2  #include  < sys / types.h >
 3  #include  < sys / socket.h >
 4  #include  < netinet / in .h >
 5  #include  < arpa / inet.h >
 6  #include  < pthread.h >
 7 
 8  #include  < string .h >
 9  #include  < errno.h >
10 
11 
12  #define  MAX_BUF 4*1024*1024
13 
14  // ip
15  static   char  szIp[ 20 =  { 0 };
16 
17  // port
18  static   int     nPort  =   0 ;
19 
20  // send times
21  static   int  nTimes  =   100 ;
22 
23  // interval between every send.(micro second)
24  static   int  nInertval  =   500000 ;
25 
26  // whether broadcast to udp when sending.
27  static   int  nBroadcast  =   0 ;
28 
29  // whether output the content when sending or receiving data.
30  static   int  nVerbose  =   0 ;
31 
32  enum
33  {
34      FUN_SEND  =   1 ,
35      FUN_RECV  =   2 ,
36  };
37  // whether sending/recving/testfilter data.
38  // 1 -send
39  // 2 -recv
40  // 3 -testfilter
41  static   int  nFunction  =  FUN_SEND;
42 
43  enum
44  {
45      PROTOCOL_UDP  =   1 ,
46      PROTOCOL_TCP  =   2 ,
47  };
48  // the protocol used.
49  // 1 -udp
50  // 2 -tcp
51  static   int  nProtocol  =  PROTOCOL_UDP;
52 
53  // file to read from the content for sending.
54  static   char  szFile_Send[ 100 =  { " ./cmd " };
55  static   int  nSendHostPort  =   203901 ;
56 
57  // whether receiveing data.
58  // file to save the recving data.
59  static   char  szFile_Recv[ 100 =  { 0 };
60  // whether save the receiving data.1-save;others-not save.
61  static   int     nFileSave  =   0 ;
62  static  FILE *  file_save  =  NULL;
63      
64  static   char  szTime[ 20 =  { " 2011-04-18 10:21:22 " };
65 
66  static   void  testsleep();
67  static   void  mysleep( int  n);
68  static   char *  mytime();
69  void  createthread( void *  fun,  void *  argv);
70 
71  static   void  usage();
72  static   int  doParams( int  argc, void **  argv);
73  static   int  JoinGroup( int  sock);
74  static   int  setPortReuse( int  sock);
75  static   int  setTTL( int  sock,  int  TTL);
76  static   int  socket4send();
77  static   int  socket4recv();
78  static   int  readCmd( char *  pBuf);
79  static   void sending();

80 static void recving();

 

  1  /*
  2  void char* mytime()
  3  {
  4      int time = time(NULL);
  5      struct tm =
  6  }
  7  */
  8 
  9  void  testsleep()
 10  {
 11      printf( " [testsleep].begin\n " );
 12      usleep( 10000000 );
 13      printf( " [testsleep].end\n " );
 14  }
 15 
 16  void  mysleep( int  n)
 17  {
 18       if (n  < 1000000 )
 19      {
 20          usleep(n);
 21      }
 22       else
 23      {
 24          sleep(n / 1000000 );
 25      }
 26  }
 27 
 28  void  createthread( void *  fun,  void *  argv)
 29  {
 30      pthread_attr_t attr;
 31      pthread_t thrd;
 32       struct  sched_param sched_param_config;
 33      pthread_attr_init( & attr);
 34      pthread_attr_setdetachstate( & attr,PTHREAD_CREATE_DETACHED);
 35      pthread_attr_setschedpolicy( & attr,SCHED_FIFO);
 36      sched_getparam( 0 , & sched_param_config);
 37      sched_param_config.sched_priority  =  sched_get_priority_max(SCHED_FIFO);
 38      pthread_attr_setschedparam( & attr, & sched_param_config);
 39 
 40      pthread_create( & thrd, & attr,fun, argv);
 41  }
 42 
 43  void  usage()
 44  {
 45      printf( " usage: xsock ip port [-times=] [-inertval(us)=] [-file=][options]\n " );
 46      printf( " \t\e[34m\e[1mip:\e[0m \t\tthe ip address to send to or receive from.\n " );
 47      printf( " \t\t\twhen sending,it specify the destination host.\n " );
 48      printf( " \t\t\twhen sending multi-broadcast with -b option,it's the broadcast address(224.0.0.0 to 239.255.255.255).\n " );
 49      printf( " \t\t\twhen normal receiving,it's meanless and ignored(but you should still specify it with any valid value,such as 127.0.0.1).\n " );
 50      printf( " \t\t\twhen receiving multi-broadcast with -b option,it specify the destination address(224.0.0.0 to 239.255.255.255).\n " );
 51      printf( " \t\e[34m\e[1mport:\e[0m \tthe port to send to or receive from.\n " );
 52      printf( " \t\t\twhen sending,it specify the destination port.\n " );
 53      printf( " \t\t\twhen sending multi-broadcast with -b option,it's the broadcast port.\n " );
 54      printf( " \t\t\twhen normal receiving,it's the port of localthost to receive the data.\n " );
 55      printf( " \t\t\twhen receiving multi-broadcast with -b option,it specify the destination port.\n " );
 56      printf( " \t\e[34m\e[1m[-times]:\e[0m \ttimes of sending when use -send option.DEFAULT:100\n " );
 57      printf( " \t\e[34m\e[1m[-inertval(us)]:\e[0m interval time(u seconds) of sending when use -send option.DEFAULT:500000\n " );
 58      printf( " \t\e[34m\e[1m[-file]:\e[0m \tthe file where to read from the content when sending,or the file to save the received data when receiving.\n " );
 59      printf( " \t\t\tDEFAULT:'./cmd' for send, NULL for receive(the data won't be saved as a file if -file=FILE is not spcified when receiving).\n " );
 60      printf( " \t\e[34m\e[1m[options]:\e[0m \t-tcp   use tcp protocol to send or receive.\n " );
 61      printf( " \t\t\t -udp   use udp protocol ro send or receive.it's the default option.\n " );
 62      printf( " \t\t\t -send  send data.\n " );
 63      printf( " \t\t\t -recv  receive data.\n " );
 64      printf( " \t\t\t -b  mutilbrocast when use udp protocol to send or receive.\n " );
 65      printf( " \t\t\t -v  output verbose data when sending or receiving.\n " );
 66  }
 67 
 68  int  doParams( int  argc, void **  argv)
 69  {
 70       int  nRet  =   0 ;
 71 
 72       int  nTemp  =   0 ;
 73       char  szTemp[ 100 =  { 0 };
 74 
 75       int  i  =   0 ;
 76       for (i = 0 ; i < argc; i ++ )
 77      {
 78           if (i  ==   1 )
 79          {
 80                  strcpy(szIp, argv[i]);
 81          }
 82           else   if (i  ==   2 )
 83          {
 84                  nPort  =  atoi(argv[i]);
 85          }
 86           else   if (strcmp(argv[i],  " -v " ==   0 )
 87          {
 88                  nVerbose  =   1 ;
 89          }
 90           else   if (strcmp(argv[i],  " -b " ==   0 )
 91          {
 92                  nBroadcast  =   1 ;
 93          }
 94           else   if (strcmp(argv[i],  " -send " ==   0 )
 95          {
 96                  nFunction  =  FUN_SEND;
 97          }
 98           else   if (strcmp(argv[i],  " -recv " ==   0 )
 99          {
100              nFunction  =  FUN_RECV;
101          }
102           else   if (strcmp(argv[i],  " -tcp " ==   0 )
103          {
104                  nProtocol  =  PROTOCOL_TCP;
105          }
106           else   if (strcmp(argv[i],  " -udp " ==   0 )
107          {
108                  nProtocol  =  PROTOCOL_UDP;
109          }
110           else   if ( sscanf(argv[i],  " -file=%s " , szTemp) > 0 )
111          {
112                  strcpy(szFile_Send, szTemp);
113                  strcpy(szFile_Recv, szTemp);
114              nFileSave  =   1 ;
115          }
116           else   if ( sscanf(argv[i],  " -times=%d " & nTemp) > 0 )
117          {
118                  nTimes  = nTemp;
119          }
120           else   if ( sscanf(argv[i],  " -interval=%dus " & nTemp) > 0 )
121          {
122                  nInertval  = nTemp;
123          }
124      }
125 
126       return  nRet;
127  }
128 
129  int  JoinGroup( int  sock)
130  {
131       if (sock  <=   0 )
132 
133      printf( " join group: %s... " , szIp);
134      {
135           return   - 1 ;
136      }
137 
138       struct  ip_mreq mreq;
139      mreq.imr_multiaddr.s_addr  =  inet_addr(szIp);
140      mreq.imr_interface.s_addr  =  htonl(INADDR_ANY);
141       if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, ( char * ) & mreq,  sizeof (mreq))  <   0 )
142      {
143          printf( " failed! %s\n " , strerror(errno));
144           return   - 1 ;
145      }
146       else
147      {
148          printf( " ok\n " );
149      }
150 
151       return   0 ;
152  }
153 
154  int  setPortReuse( int  sock)
155  {
156       if (sock  <=   0 )
157      {
158           return   - 1 ;
159      }
160 
161       int  value  =   1 ;
162       if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,  & value,  sizeof (value) ) <   0 )
163      {
164          printf( " setPortReuse() failed! %s\n " ,strerror(errno));
165           return   - 1 ;
166      }
167 
168       return   0 ;
169  }
170 
171  int  setTTL( int  sock,  int  TTL)
172  {
173       if ( (sock  <=   0 ||  (TTL  <=   0 ||  (TTL  >=   256 ))
174      {
175           return   - 1 ;
176      }
177 
178        // unsigned char TTL = 65;
179        if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, ( char   * ) & TTL,  sizeof (TTL))  <   0 )
180       {
181          printf( " [setTTL] set  ttl to %d failed, %s\n " 65 , strerror(errno));
182           return   - 1 ;
183       }
184 
185        return   0;

186 } 

 

   1 int socket4send()

  2  {
  3       int  sock  =   0 ;
  4       if (nProtocol  ==  PROTOCOL_UDP) // udp
  5      {
  6          sock  =  socket(AF_INET,  SOCK_DGRAM,  IPPROTO_UDP);
  7      }
  8       else   if (nProtocol  ==  PROTOCOL_TCP)
  9      {
 10          sock  =  socket(AF_INET,  SOCK_STREAM, IPPROTO_TCP);
 11      }
 12 
 13       if (sock  <=   0 )
 14      {
 15          printf( " [socket] failed! %s\n " , strerror(errno));
 16      }
 17 
 18      setPortReuse(sock);
 19 
 20       if (nProtocol  ==  PROTOCOL_UDP) // udp.on some routers, if the ttl is too small, the multi-broadcast packet will lose.
 21      {
 22      setTTL(sock,  65 );
 23      }
 24 
 25       struct  sockaddr_in Addr;
 26      Addr.sin_family  =  AF_INET;
 27      Addr.sin_port  =  htons( 203901 );
 28      Addr.sin_addr.s_addr  =  INADDR_ANY;
 29 
 30       if (bind(sock, ( struct  sockaddr * ) & Addr,  sizeof (Addr))  <   0 )
 31      {
 32          printf( " [bind]error. %s\n " , strerror(errno));
 33           return   - 1 ;
 34      }
 35 
 36       return  sock;
 37  }
 38 
 39  int  socket4recv()
 40  {
 41       int  sock  =   0 ;
 42 
 43       if (nProtocol  ==  PROTOCOL_UDP) // udp
 44      {
 45          sock  =  socket(AF_INET,  SOCK_DGRAM,  IPPROTO_UDP);
 46      }
 47       else   if (nProtocol  ==  PROTOCOL_TCP)
 48      {
 49          sock  =  socket(AF_INET,  SOCK_STREAM, IPPROTO_TCP);
 50      }
 51 
 52       if (sock  <=   0 )
 53      {
 54          printf( " [socket] failed! %s\n " , strerror(errno));
 55      }
 56      
 57      setPortReuse(sock);
 58 
 59       struct  sockaddr_in Addr;
 60      Addr.sin_family  =  AF_INET;
 61      Addr.sin_port  =  htons(nPort);
 62      Addr.sin_addr.s_addr  =  INADDR_ANY;
 63       if (nBroadcast  ==   1 ) // if to receive udp multibroadcast,should specify the ip.
 64      {
 65          Addr.sin_addr.s_addr  =  inet_addr(szIp);
 66      }
 67 
 68       if (bind(sock, ( struct  sockaddr * ) & Addr,  sizeof (Addr))  <   0 )
 69      {
 70          printf( " [bind]error. %s\n " , strerror(errno));
 71          
 72          close(sock);
 73           return   - 1 ;
 74      }
 75 
 76       if (nProtocol  ==  PROTOCOL_UDP)
 77      {
 78           if (nBroadcast  ==   1 ) // join the udp multicast address.
 79          {
 80              JoinGroup(sock);
 81          }
 82      }
 83       else   if (nProtocol  ==  PROTOCOL_TCP) // for tcp connection,we must listen.
 84      {
 85           if (listen(sock,  5000 ==   0 )
 86          {
 87              printf( " listening on port:%d...\n " , nPort);
 88          }
 89           else
 90          {
 91              printf( " listen failed!%s\n " , strerror(errno));
 92 
 93              close(sock);
 94              sock  =   - 1 ;
 95          }
 96      }
 97      
 98       return  sock;
 99  }
100 
101  int  readCmd( char *  pBuf)
102  {
103       int  nRet  =   - 1 ;
104       if (pBuf  !=  NULL)
105      {
106          FILE *  file  =  fopen(szFile_Send,  " r " );
107           if (file  !=  NULL)
108          {
109              nRet  =  fread(pBuf,  1 , MAX_BUF, file);
110 
111              fclose(file);
112              file  =  NULL;
113          }
114           else
115          {
116              printf( " [readCmd].open file:%s failed! %s\n " , szFile_Send, strerror(errno));
117          }
118          nRet  =  strlen(pBuf);
119      }
120 
121       return  nRet;
122  }
  1  void  sending()
  2  {
  3       // open the socket
  4       int  sender  =  socket4send();
  5       if (sender  <=   0 )
  6      {
  7           return ;
  8      }
  9 
 10       struct  sockaddr_in to_addr;
 11       int  to_len  =   sizeof ( struct  sockaddr_in);
 12      to_addr.sin_family  =  AF_INET;
 13      to_addr.sin_port  =  htons(nPort);
 14      to_addr.sin_addr.s_addr  =  inet_addr(szIp);
 15 
 16       // read the cmd.
 17       char   * szTemp  =  ( char * )malloc( sizeof ( char ) * MAX_BUF);
 18       if (readCmd(szTemp)  >   0 )
 19      {
 20           if (nVerbose  ==   1 )
 21          {
 22              printf( " <<<<<<<<<<<<<<<<<<<<  CONTENT >>>>>>>>>>>>>>>\n " );
 23              printf( " %s " , szTemp);
 24              printf( " <<<<<<<<<<<<<<<<<<<<    END    >>>>>>>>>>>>>>>\n " );
 25          }
 26 
 27           // if(nProtocol == 2) // tcp,need to connet
 28          {
 29               if (connect(sender, ( struct  sockaddr_in * ) & to_addr, to_len)  ==   0 )
 30                  {
 31               int  i  =   0 ;
 32               for (i = 0 ; i <  nTimes; i ++ )
 33              {
 34                  printf( " [%d]\tsending... " , i + 1 );
 35 
 36                   int  nsent  =   0  ;
 37                   // if(nProtocol == 1)
 38                  {
 39                  nsent  =  sendto(sender, ( void * )szTemp, strlen(szTemp),  0 , ( struct  sockaddr_in * ) & to_addr, to_len);
 40                  }
 41                   // else if(nProtocol == 2)
 42                  {
 43                   // nsent = sendto(sender, (void*)szTemp, strlen(szTemp), 0, (struct sockaddr_in*)&to_addr, to_len);
 44                   // nsent = send(sender, (void*)szTemp, strlen(szTemp), 0);
 45                  }
 46 
 47                   if (nsent  ==  strlen(szTemp))
 48                  {
 49                  printf( " ok! sent = %d\n " , nsent);
 50                  }
 51                   else
 52                  {
 53                  printf( " failed!sent = %d. %s\n " , nsent, strerror(errno));
 54                  }
 55 
 56                   if (i  <  (nTimes - 1 ))
 57                  {
 58                  mysleep(nInertval);
 59                  }
 60              }
 61           
 62              }
 63               else
 64          {
 65                  printf( " connect() failed!%s\n " , strerror);
 66          }        
 67          }
 68          
 69      }
 70 
 71      free(szTemp);
 72      close(sender);
 73  }
 74 
 75  void  recving_savefile( char *  p)
 76  {
 77       if (file_save  ==  NULL)
 78      {
 79              file_save  =  fopen(szFile_Recv,  " w " );
 80      }
 81 
 82       if (fwrite(p,  1 , strlen(p), file_save)  <=   0 )
 83      {
 84          printf( " %s\n " , strerror(errno));
 85      }
 86      fflush(file_save);
 87  }
 88 
 89  void  recving_tcp_thread( void *  argv)
 90  {
 91      printf( " recving_tcp_thread() start.\n " );
 92 
 93       int  sock  =   * (( int * )argv);
 94 
 95       char   * pTemp  =  ( char * )malloc( sizeof ( char ) * MAX_BUF);
 96       while ( 1 )
 97      {
 98           int  nRecv  =  recv(sock, pTemp, MAX_BUF,  0 );
 99           if  (nRecv  <=   0 )
100       {
101           if (nRecv  ==   0 )
102          {
103              printf( " connection 0x%x closed.\n\n " , sock);
104          }
105           else
106          {
107              printf( " connection 0x%x recv error.%s\n\n " , sock, strerror(errno));
108          }
109 
110              close(sock);
111                break ;        
112      }
113 
114      printf( " 0x%x: [recv]. len = %d\n " , sock, nRecv);        
115           if (nVerbose  ==   1 )
116          {
117              printf( " %s\n " , pTemp);
118          }
119      
120       if (nFileSave  ==   1 )
121      {
122          recving_savefile(pTemp);
123      }    
124      }
125 
126      free(pTemp);
127      close(sock);
128  }
129 
130  void  recving()
131  {
132       int  sock  =  socket4recv();
133       if (sock  <=   0 )
134      {
135           return ;
136      }
137 
138       char   * pTemp  =  ( char * )malloc( sizeof ( char ) * MAX_BUF);
139 
140       int  new_sock;
141       struct  sockaddr_in from;
142       int  from_len;
143 
144       while ( 1 )
145      {
146           if (nProtocol  ==  PROTOCOL_UDP)  // udp
147          {
148               if (recvfrom(sock, pTemp, MAX_BUF,  0 , ( struct  sockaddr_in * ) & from,  & from_len)  >   0 )
149              {
150                  printf( " [recvfrom]:[%s:%d], len =%d\n " ,  inet_ntoa(from.sin_addr), ntohs(from.sin_port),  strlen(pTemp));
151 
152                   if (nVerbose  ==   1 )
153                  {
154                      printf( " %s\n " , pTemp);
155                  }
156 
157                   if (nFileSave  ==   1 )
158                  {
159                      recving_savefile(pTemp);
160                  }
161              }
162          }
163           else   if (nProtocol  ==  PROTOCOL_TCP) // tcp
164          {
165              new_sock  =  accept(sock, ( struct  sockaddr_in * ) & from,  & from_len);
166              printf( " new connection(0x%x) to [%s:%d].\n " ,  new_sock, inet_ntoa(from.sin_addr), ntohs(from.sin_port));
167 
168              createthread(recving_tcp_thread, ( void * ) & new_sock);
169              }
170      }
171 
172      free(pTemp);
173     close(sock);

174 } 

 

  1 int main(int argc,void** argv)

 2  {
 3       // process the params.
 4       if (argc  < 3   ||  (doParams(argc, argv)  <   0 ))
 5      {
 6          usage();
 7           return ;
 8      }
 9 
10       if (nFunction  ==  FUN_SEND)
11      {
12          sending();
13      }
14       else   if (nFunction  ==  FUN_RECV)
15      {
16          recving();
17      }
18  }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


转载于:https://www.cnblogs.com/chutianyao/archive/2011/05/02/2034426.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值