您的位置:首页 > 理论基础 > 计算机网络

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

2011-05-02 16:29 1031 查看
最近项目中大量使用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>

#define MAX_BUF 4*1024*1024

//ip
static char szIp[20] = {0};

//port
static int nPort = 0;

//send times
static int nTimes = 100;

//interval between every send.(micro second)
static int nInertval = 500000;

//whether broadcast to udp when sending.
static int nBroadcast = 0;

//whether output the content when sending or receiving data.
static int nVerbose = 0;

enum
{
FUN_SEND = 1,
FUN_RECV = 2,
};
//whether sending/recving/testfilter data.
//1 -send
//2 -recv
//3 -testfilter
static int nFunction = FUN_SEND;

enum
{
PROTOCOL_UDP = 1,
PROTOCOL_TCP = 2,
};
//the protocol used.
//1 -udp
//2 -tcp
static int nProtocol = PROTOCOL_UDP;

//file to read from the content for sending.
static char szFile_Send[100] = {"./cmd"};
static int nSendHostPort = 203901;

//whether receiveing data.
//file to save the recving data.
static char szFile_Recv[100] = {0};
//whether save the receiving data.1-save;others-not save.
static int nFileSave = 0;
static FILE* file_save = NULL;

static char szTime[20] = {"2011-04-18 10:21:22"};

static void testsleep();
static void mysleep(int n);
static char* mytime();
void createthread(void* fun, void* argv);

static void usage();
static int doParams(int argc,void** argv);
static int JoinGroup(int sock);
static int setPortReuse(int sock);
static int setTTL(int sock, int TTL);
static int socket4send();
static int socket4recv();
static int readCmd(char* pBuf);
static void sending(); 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 {
nFunction = FUN_RECV;
}
else if(strcmp(argv[i], "-tcp") == 0)
{
nProtocol = PROTOCOL_TCP;
}
else if(strcmp(argv[i], "-udp") == 0)
{
nProtocol = PROTOCOL_UDP;
}
else if( sscanf(argv[i], "-file=%s", szTemp)>0)
{
strcpy(szFile_Send, szTemp);
strcpy(szFile_Recv, szTemp);
nFileSave = 1;
}
else if( sscanf(argv[i], "-times=%d", &nTemp)>0)
{
nTimes =nTemp;
}
else if( sscanf(argv[i], "-interval=%dus", &nTemp)>0)
{
nInertval =nTemp;
}
}

return nRet;
}

int JoinGroup(int sock)
{
if(sock <= 0)

printf("join group: %s...", szIp);
{
return -1;
}

struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(szIp);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if(setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq)) < 0)
{
printf("failed! %s\n", strerror(errno));
return -1;
}
else
{
printf("ok\n");
}

return 0;
}

int setPortReuse(int sock)
{
if(sock <= 0)
{
return -1;
}

int value = 1;
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value) )< 0)
{
printf("setPortReuse() failed! %s\n",strerror(errno));
return -1;
}

return 0;
}

int setTTL(int sock, int TTL)
{
if( (sock <= 0) || (TTL <= 0) || (TTL >= 256))
{
return -1;
}

//unsigned char TTL = 65;
if(setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&TTL, sizeof(TTL)) < 0)
{
printf("[setTTL] set ttl to %d failed, %s\n", 65, strerror(errno));
return -1;
}

return 0; }

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 }

int readCmd(char* pBuf)
{
int nRet = -1;
if(pBuf != NULL)
{
FILE* file = fopen(szFile_Send, "r");
if(file != NULL)
{
nRet = fread(pBuf, 1, MAX_BUF, file);

fclose(file);
file = NULL;
}
else
{
printf("[readCmd].open file:%s failed! %s\n", szFile_Send, strerror(errno));
}
nRet = strlen(pBuf);
}

return nRet;
} 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)
{
if(nRecv == 0)
{
printf("connection 0x%x closed.\n\n", sock);
}
else
{
printf("connection 0x%x recv error.%s\n\n", sock, strerror(errno));
}

close(sock);
break;
}

printf("0x%x: [recv]. len = %d\n", sock, nRecv);
if(nVerbose == 1)
{
printf("%s\n", pTemp);
}

if(nFileSave == 1)
{
recving_savefile(pTemp);
}
}

free(pTemp);
close(sock);
}

void recving()
{
int sock = socket4recv();
if(sock <= 0)
{
return;
}

char *pTemp = (char*)malloc(sizeof(char)*MAX_BUF);

int new_sock;
struct sockaddr_in from;
int from_len;

while(1)
{
if(nProtocol == PROTOCOL_UDP) //udp
{
if(recvfrom(sock, pTemp, MAX_BUF, 0, (struct sockaddr_in*)&from, &from_len) > 0)
{
printf("[recvfrom]:[%s:%d], len =%d\n", inet_ntoa(from.sin_addr), ntohs(from.sin_port), strlen(pTemp));

if(nVerbose == 1)
{
printf("%s\n", pTemp);
}

if(nFileSave == 1)
{
recving_savefile(pTemp);
}
}
}
else if(nProtocol == PROTOCOL_TCP)//tcp
{
new_sock = accept(sock, (struct sockaddr_in*)&from, &from_len);
printf("new connection(0x%x) to [%s:%d].\n", new_sock, inet_ntoa(from.sin_addr), ntohs(from.sin_port));

createthread(recving_tcp_thread, (void*)&new_sock);
}
}

free(pTemp);
close(sock); }

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
if(nFunction == FUN_SEND)
{
sending();
}
else if(nFunction == FUN_RECV)
{
recving();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: