• 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 }


  • 相关阅读:
    windows查看端口命令
    lombok
    Linux之文档与目录结构 目录的相关操作 Linux的文件系统
    VMware与Centos系统安装 和重置root密码
    shell 基本命令
    centos 安装教程 服务器配置教程 服务器中安装python 服务器中安装Django 安装MySQL 配置MySQL
    {Django基础十之Form和ModelForm组件}一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 ModelForm
    {Django基础九之中间件} 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证
    {Django基础八之cookie和session}一 会话跟踪 二 cookie 三 django中操作cookie 四 session 五 django中操作session
    老师的blog整理 .网络编程部分 .网络编程部分 前端部分 django基础部分
  • 原文地址:https://www.cnblogs.com/chutianyao/p/2034426.html
Copyright © 2020-2023  润新知