1/* this program is used to test UDP networking in Android.
2 * used to debug the emulator's networking implementation
3 */
4#define  PROGNAME      "test_udp"
5#define  DEFAULT_PORT  7000
6
7#include <arpa/inet.h>
8#include <netinet/in.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <sys/types.h>
12#include <sys/socket.h>
13#include <unistd.h>
14#include <string.h>
15
16#define BUFLEN 512
17#define NPACK  10
18
19void diep(char *s)
20{
21    perror(s);
22    exit(1);
23}
24
25static void
26usage(int  code)
27{
28    printf("usage: %s [options]\n", PROGNAME);
29    printf("options:\n");
30    printf("    -p<port>  use specific port (default %d)\n", DEFAULT_PORT);
31    printf("    -a<inet>  use specific IP address\n");
32    printf("    -s        run server (default is client)\n");
33    exit(code);
34}
35
36int main(int  argc, char**  argv)
37{
38    int   runServer = 0;
39    int   udpPort   = DEFAULT_PORT;
40    int   useLocal  = 0;
41    int   address   = htonl(INADDR_ANY);
42
43    struct sockaddr_in si_me, si_other;
44    int s, i, slen=sizeof(si_other);
45    char buf[BUFLEN];
46
47    while (argc > 1 && argv[1][0] == '-') {
48        const char*  optName = argv[1]+1;
49        argc--;
50        argv++;
51
52        switch (optName[0]) {
53            case 'p':
54                udpPort = atoi(optName+1);
55                if (udpPort < 1024 || udpPort > 65535) {
56                    fprintf(stderr, "UDP port must be between 1024 and 65535\n");
57                    exit(1);
58                }
59                break;
60
61            case 's':
62                runServer = 1;
63                break;
64
65            case 'a':
66                if (inet_aton(optName+1, &si_other.sin_addr) == 0)
67                    diep("inet_aton");
68                address = si_other.sin_addr.s_addr;
69                break;
70
71            default:
72                usage(1);
73        }
74    }
75
76    if (runServer) {
77        if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
78        diep("socket");
79
80        memset((char *) &si_me, 0, sizeof(si_me));
81        si_me.sin_family      = AF_INET;
82        si_me.sin_port        = htons(udpPort);
83        si_me.sin_addr.s_addr = address;
84        if (bind(s, (struct sockaddr*)&si_me, sizeof(si_me))==-1)
85            diep("bind");
86
87        printf("UDP server listening on %s:%d\n", inet_ntoa(si_me.sin_addr), udpPort);
88        for (i=0; i<NPACK; i++) {
89        if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr*)&si_other, (socklen_t*)&slen)==-1)
90            diep("recvfrom()");
91        printf("Received packet from %s:%d\nData: %s\n\n",
92                inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);
93        }
94
95        printf("UDP server closing\n");
96        close(s);
97    }
98    else  /* !runServer */
99    {
100        if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
101            diep("socket");
102
103        memset((char *) &si_other, 0, sizeof(si_other));
104        si_other.sin_family = AF_INET;
105        si_other.sin_port = htons(udpPort);
106        si_other.sin_addr.s_addr = address;
107
108        printf("UDP client sending packets to %s:%d\n", inet_ntoa(si_other.sin_addr), udpPort);
109
110        for (i=0; i<NPACK; i++) {
111            printf("Sending packet %d\n", i);
112            sprintf(buf, "This is packet %d\n", i);
113            if (sendto(s, buf, BUFLEN, 0, (struct sockaddr*)&si_other, slen)==-1)
114            diep("sendto()");
115        }
116
117        close(s);
118        printf("UDP client closing\n");
119    }
120    return 0;
121}
122