-
Notifications
You must be signed in to change notification settings - Fork 1
/
udpclient.c
123 lines (95 loc) · 3.31 KB
/
udpclient.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <time.h>
#ifndef WIN32
#include <netdb.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#else
#define WINVER 0x0501
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#endif
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#define BUFSIZE 4096
int s_send = -1;
unsigned char buf[BUFSIZE];
int main(int argc, char* argv[]) {
if (argc>=2 && !strcmp(argv[1], "--version")) {
printf("udpclient 0.0\n");
return 0;
}
if (argc<5 || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-?")) {
fprintf (stderr,
"simple UDP client\n"
"Algorithm:\n"
"1. Read input from stdin;\n"
"2. Send UDP packets (all the same) to destination and listen for replies;\n"
"3. After the first reply dump it to stdout and exit.\n"
"Buffer size (maximum input and output sizes) is %d bytes\n"
"IPv6 is supported when you use respective send_addr\n"
"\n"
"Implemented by Vitaly _Vi Shukela in 2013, License=MIT\n"
"\n"
"Usage:\n"
"\tudpclient count interval send_host send_port < input > output\n"
"Example:\n"
"\techo eth0 | udpserv 10 25000 1.2.3.4 6767 \n"
,BUFSIZE);
return 1;
}
struct addrinfo hints;
struct addrinfo *send_addr;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
int count = atoi(argv[1]);
int usleep_interval = atoi(argv[2]);
char* send_host = argv[3];
char* send_port = argv[4];
if (!strcmp(send_host, "NULL")) send_host=NULL;
if (!strcmp(send_port, "NULL")) send_port=NULL;
int gai_error;
gai_error=getaddrinfo(send_host,send_port, &hints, &send_addr);
if (gai_error) { fprintf(stderr, "getaddrinfo 1: %s\n",gai_strerror(gai_error)); return 4; }
if (!send_addr) { fprintf(stderr, "getaddrinfo returned no addresses\n"); return 6; }
if (send_addr->ai_next) {
fprintf(stderr, "Warning: using only one of addresses retuned by getaddrinfo\n");
}
s_send = socket(send_addr->ai_family, send_addr->ai_socktype, send_addr->ai_protocol);
if (s_send == -1) { perror("socket"); return 7; }
{
int one = 1;
setsockopt(s_send, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
fcntl(s_send, F_SETFL, O_NONBLOCK);
}
if (connect(s_send, send_addr->ai_addr, send_addr->ai_addrlen)) { perror("bind"); return 5; }
int data_size;
data_size = fread(&buf, 1, sizeof buf, stdin);
fclose(stdin);
int i;
for (i=0;i<count;++i) {
int ret = send(s_send, buf, data_size, 0);
if(ret!=data_size) perror("send");
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(s_send, &rfds);
struct timeval tv = {usleep_interval/1000000,(usleep_interval%1000000)};
ret = select(s_send+1, &rfds, NULL, NULL, &tv);
if (FD_ISSET(s_send, &rfds)) {
ret = recv(s_send, buf, sizeof buf, 0);
if(ret>=0) {
fwrite(buf, 1, ret, stdout);
break;
}
}
}
if(i==count)return 1;
return 0;
}