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 }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


posted @ 2011-05-02 16:29    阅读(7985)  评论(3编辑  收藏  举报