difference in received data thgrough listener.c and netcat

I build a simple UDP server which listens continuouls to the hexadecimal datagrams sends from a client.
Client specification IP - 192.168.37.1 port - 1901
The Program is as follows // source :beej

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
/*
** listener.c -- a datagram sockets "server" demo
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#define MYPORT "1901"    // the port users will be connecting to

#define MAXBUFLEN 100

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(void)
{
    int sockfd;
    struct addrinfo hints, *servinfo, *p;
    int rv;
    int numbytes;
    struct sockaddr_storage their_addr;
    char buf[MAXBUFLEN];
    char buffer[MAXBUFLEN];
    socklen_t addr_len;
    char s[INET6_ADDRSTRLEN];
    int k = 0;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET; // set to AF_INET to force IPv4
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_flags = AI_PASSIVE; // use my IP

    if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    // loop through all the results and bind to the first we can
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype,
                p->ai_protocol)) == -1) {
            perror("listener: socket");
            continue;
        }

        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            close(sockfd);
            perror("listener: bind");
            continue;
        }

        break;
    }

    if (p == NULL) {
        fprintf(stderr, "listener: failed to bind socket\n");
        return 2;
    }

    freeaddrinfo(servinfo);

    printf("listener: waiting to recvfrom...\n");
    while(1) {
    addr_len = sizeof their_addr;
    if ((numbytes = recvfrom(sockfd, buf, sizeof(buf) , 0,(struct sockaddr *)&their_addr, &addr_len)) == -1) {
        perror("recvfrom");
        exit(1);
    }

    printf("listener: got packet from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s));
    printf("listener: packet is %02x bytes long\n", numbytes);
    //buf[numbytes] = '\0';
    buffer[k] = buf[k];
    //printf("listener: packet contains %d\n", (unsigned char)buffer);
    printf("listener: packet contains %02x\n", buf);
    }
    close(sockfd);

    return 0;
}



Output :


bsnayak@ubuntu:~/Desktop/learn$ ./server
listener: waiting to recvfrom...
listener: got packet from 192.168.37.1
listener: packet is 64 bytes long
listener: packet contains 5ca0a130
listener: got packet from 192.168.37.1
listener: packet is 64 bytes long
listener: packet contains 5ca0a130
listener: got packet from 192.168.37.1
listener: packet is 64 bytes long
listener: packet contains 5ca0a130
listener: got packet from 192.168.37.1
listener: packet is 64 bytes long
listener: packet contains 5ca0a130




But when i run it through NETCAT i get the following output


bsnayak@ubuntu:~$ nc -u -l 192.168.37.134 1901 | xxd -g1
0000000: 01 b2 00 14 86 50 01 01 02 01 ff ff 6c 05 fd 04  .....P......l...
0000010: e8 03 00 03 00 00 00 00 00 a0 86 01 00 00 00 03  ................
0000020: 00 00 00 00 00 83 7f 00 82 03 00 81 81 00 00 80  ................
0000030: 00 01 00 01 01 00 00 ac e2 37 38 00 00 00 ff ff  .........78.....
0000040: a0 ff ff ff 00 a0 ff ff ff 00 00 00 03 07 fb c1  ................
0000050: f0 42 16 01 00 01 00 00 00 00 01 00 00 00 00 00  .B..............
0000060: 00 00 35 09 30 09 30 09 30 09 30 09 30 09 30 09  ..5.0.0.0.0.0.0.
0000070: 30 09 30 ff ff ff ff ff ff ff ff ff ff ff ff ff  0.0.............
0000080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0000090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
00000a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
00000b0: ff ff 01 b2 00 14 87 50 01 01 02 01 ff ff 6c 05  .......P......l.
00000c0: fd 04 e8 03 00 03 00 00 00 00 00 a0 86 01 00 00  ................




What is possible wrong here? How can i get the same output like netcat in my c program also? Kindly suggest with code sample

NOTE: The clients sends datagram in 700 ms which are in the increasing manner. so i would expect the ./server will give different values like netcat.







How can i get the same output like netcat in my c program also?
By using the correct printf specifier, surely the compiler warned you that you had the wrong specifier.

 
printf("listener: packet contains %02x\n", buf);
That format code expects a number. As you've passed in buf, or more specifically the address of the first element of buf, it's formatting that number.

As it's a string, you should null terminate the string (that code you commented out in line 88) and print the string.
 
printf("listener: packet contains %s\n", buf);

http://en.cppreference.com/w/c/io/fprintf
Last edited on
Hello

I appriciate your suggestion. I have tried them too. As the client sends UDP telegrams with hex numbers it will be easy to detect it.

But here the main problem is.. if i run the server it gives the same output continuously and if i run it again and again a new hexadecimal number is produced. It seems it gives output before all packets are received.. !! (May be i am wrong)

Is there a problem with some blocking issue?? If i run my server.exe file in every 600 mili seconds i will get the outputs continuously..

Kindly suggest how can i make it parallel ...

Last edited on
As the client sends UDP telegrams with hex numbers, ...
The client only sends a sequence of bytes. If you're not sending a string, can you post the client code, so we can be clear what's going on.

It seems it gives output before all packets are received.
The server is printing each datagram as it arrives. We can't comment further on the behaviour of the server unless we see the client.
Hello.. Here client is a Software setup which generates hexadecimal datagrams every 10 milliseconds and they are genrated in a increasing order. As with the NC command you can see the datagrams received are in the increasing order

0000000: 01 b2 00 14 86 50 01 01 02 01 ff ff 6c 05 fd 04 .....P......l...
0000010: e8 03 00 03 00 00 00 00 00 a0 86 01 00 00 00 03 ................
0000020: 00 00 00 00 00 83 7f 00 82 03 00 81 81 00 00 80 ................

Why i am not receiving the same with my server.c code?

It gives the same string each time until i disconnect the server and run it again.

Why the server and NC are showing different outputs? What can cause this difference?
Why i am not receiving the same with my server.c code?
Of course, you'll receive the same data if the client is rerun.

Here client is a Software setup which generates hexadecimal datagrams every 10 milliseconds and they are genrated in a increasing order.
I may be missing something, but I don't see any increasing order pattern.

However, if the client is sending binary number and you want a hex dump of what's send, the code looks something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
while(1) {
    sockaddr_in their_addr;
    socklen_t addr_len = sizeof their_addr;
    char buf[MAXBUFLEN];
    int numbytes;
    if ((numbytes = recvfrom(sockfd, buf, sizeof(buf) , 0,(struct sockaddr *)&their_addr, &addr_len)) == -1) {
        perror("recvfrom");
        exit(1);
    }

    for (int i = 0; i < numbytes; ++i)
        printf("%02x", buf[i]);
}
Last edited on
Hi..

Thank you . It is working fine and receiving the packets as expected.

But i extended my work with the following code. and having some problem. I am sure here i can get a solution. As my goal was to receive from clients and send it to another server. I did it like this (i used select as i have to later receive datas from multiple clients).

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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165

//Main SERVER
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/select.h>//use select() for multiplexing
#include <sys/fcntl.h> // for non-blocking

#define MAX_LENGTH 100000
#define PORT 1901

/* Select() params
 * int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
 * FD_SET(int fd, fd_set *set);
 * FD_CLR(int fd, fd_set *set);
 * FD_ISSET(int fd, fd_set *set);
 * FD_ZERO(fd_set *set);
*/

void error(char *message)
{
    perror(message);
    exit(1);
}

int main()
{

  // select parameters declared
  fd_set original_socket;
  fd_set original_stdin;
  fd_set readfds;
  fd_set writefds;
  struct timeval tv;
  int numfd, numfd2;

  // socket parameters declared
  int socket_fd_ob, socket_fd_hm;
  int bytes_read, bytes_sent;
  char address_length, address_length2;
  char recieve_data[MAX_LENGTH];
  char send_data[MAX_LENGTH];
  struct sockaddr_in server_address_ob, server_address_hm, client_address;
  int z = 0;

  //Socket creation done separately for both OB and HM communications
  if ((socket_fd_ob = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 
  {
      error("socket()");
  }
  if ((socket_fd_hm = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 
  {
      error("socket()");
  }

  
  fcntl(socket_fd_ob, F_SETFL, O_NONBLOCK); //set socket to non-blocking
  fcntl(socket_fd_hm, F_SETFL, O_NONBLOCK); //set socket to non-blocking

  // clear the set ahead of time
  FD_ZERO(&original_socket);
  FD_ZERO(&original_stdin);
  FD_ZERO(&readfds);
  FD_ZERO(&writefds);
  
  // add our descriptors to the set (0 - stands for STDIN)
  FD_SET(socket_fd_ob, &original_socket);//instead of 0 put socket_fd_ob
  FD_SET(socket_fd_ob, &readfds);
  FD_SET(0,&original_stdin);
  FD_SET(0, &writefds);

  // since we got s2 second, it's the "greater", so we use that for
  // the n param in select()
  numfd  = socket_fd_ob + 1;
  numfd2 = socket_fd_hm + 1;
  

  // wait until either socket has data ready to be recv()d (timeout 10.5 secs)
  tv.tv_sec = 1;
  tv.tv_usec = 500000;

  server_address_ob.sin_family = AF_INET;
  server_address_ob.sin_port = htons(1901);
  server_address_ob.sin_addr.s_addr = inet_addr("127.0.0.3");
  bzero(&(server_address_ob.sin_zero),sizeof(server_address_ob));

  server_address_hm.sin_family = AF_INET;
  server_address_hm.sin_port = htons(1901);
  server_address_hm.sin_addr.s_addr = inet_addr("127.0.0.1");
  bzero(&(server_address_ob.sin_zero),sizeof(server_address_hm));

  // Bind socket to the particular addresses

  if (bind(socket_fd_ob,(struct sockaddr *)&server_address_ob, sizeof(struct sockaddr)) == -1)
  {
      error("bind()");
  }

  if (bind(socket_fd_hm,(struct sockaddr *)&server_address_hm, sizeof(struct sockaddr)) == -1)
  {
      error("bind()");
  }

  address_length  = sizeof(struct sockaddr);
  address_length2 = sizeof(struct sockaddr);

  printf("\nMain server waiting for client to respond...\n");
  fflush(stdout);
  
  while (1)
  {
    readfds = original_socket;
    writefds = original_stdin;//problem
    int recieve = select(numfd, &readfds, &writefds,/*NULL,*/ NULL, &tv);
    int sent    = select(numfd2, &readfds, &writefds,/*NULL,*/ NULL, &tv);

    if (recieve == -1 || sent == -1) 
    {
      perror("select"); // error occurred in select()
    } 
    else if (recieve == 0 || sent == 0) 
    {
      printf("Timeout occurred!  No data after 1.5 seconds.\n");
    } 
    else 
    {
        // one or both of the descriptors have data
        if (FD_ISSET(socket_fd_ob, &readfds)) //if set to read
        { 
          FD_CLR(socket_fd_ob, &readfds);
          bytes_read = recvfrom(socket_fd_ob,recieve_data,MAX_LENGTH,0,(struct sockaddr *)&client_address, &address_length); 
		  
	 for (z = 0; z < bytes_read; ++z) {
	 FD_ISSET(socket_fd_hm, &writefds);
          FD_CLR(socket_fd_hm, &writefds);
          //recvfrom speech recognition client and decide what to send to HM accordingly..
          send_data[bytes_read] = recieve_data[bytes_read];
          //block call, will wait till client enters something, before proceeding
          //send the corresponding to HM
          bytes_sent = sendto(socket_fd_hm,send_data,strlen(send_data)+1,0,(struct sockaddr *)&server_address_hm, &address_length2); 
          fflush(stdout);
		  }                  
          recieve_data[bytes_read] = '\0'; //add null to the end of the buffer
          send_data[bytes_read] = '\0'; //add null to the end of the buffer
          
          printf("\n(%s , %d) rcvd: %02x\n",inet_ntoa(client_address.sin_addr),ntohs(client_address.sin_port),recieve_data);
          printf("\n(%s , %d) sent: %02x\n",inet_ntoa(server_address_hm.sin_addr),ntohs(server_address_hm.sin_port),send_data);
        }




    } //end else
  }//end while

  close (socket_fd_ob);
  return 0;
}


The problem with this. I can realize that with a server on netcat (nc -u -l 120.0.0.1 1901) i receive the datas which is sent through "socket_fd_hm"


But in wireshark I see only receiving is done but sending is not done. Kindly suggest how can i send it the received datas to another server.


Thank you.


Last edited on
127.0.0.x addresses all bind to the same address. So 127.0.0.3 and 127.0.0.1 are not distict addresses in the same way 192.168.0.3 and 192.168.0.1 are.
so you mean. I should bind to only one address? for example- other one will work

1
2
3
4
if (bind(socket_fd_ob,(struct sockaddr *)&server_address_ob&server_address_hm, sizeof(struct sockaddr)) == -1)
  {
      error("bind()");
  }


if i take the other bind away..

It is the same but no sending is observed.i think i made some wrong understanding the use of sendto(). I mean sending the received telegram to the server at {127.0.0.1 -1901}

kindly suggest
Last edited on
I'm just saying that you think you're using two addresses, but you are, in fact, just using the same one twice.
Last edited on
are the ips 127.0.0.1/ 127.0.0.2/127.0.0.3 are directed to one. How can i make it different?
1
2
3
4
5
6
7
8
9
  server_address_ob.sin_family = AF_INET;
  server_address_ob.sin_port = htons(1901);
  server_address_ob.sin_addr.s_addr = inet_addr("127.0.0.1");
  bzero(&(server_address_ob.sin_zero),sizeof(server_address_ob));

  server_address_hm.sin_family = AF_INET;
  server_address_hm.sin_port = htons(1902);
  server_address_hm.sin_addr.s_addr = inet_addr("192.168.28.128");
  bzero(&(server_address_ob.sin_zero),sizeof(server_address_hm));


I used the following addresses but still unable to receive the datapackets sent from 127.0.0.1 to the address 192.168.28.128.


Here is the output



Main server waiting for client to respond...

(127.0.0.1 , 49331) rcvd: bfb0751c

(0.0.0.0 , 0) sent: bfb1fbbc


I should expect that it should send this message rcvd to the address and i can see it with nc -u -l 192.168.28.128 1901
Please let me know if i am doing something wrong with code?? I am not having much knowledge on this topic. Thanks
Last edited on
Topic archived. No new replies allowed.