1

I communicate with a server, i send a message with a socket (sock_raw..), it's works fine, the client (me), send the message, the server receive the right message, but when the server need to send it to me (the client), the client don't retrieve the right information with the recv from.

I retrieve this on two calls server->client :

buffer = [E] | len_buffer = [2]
buffer = [E] | len_buffer = [2]

But my buffer need to be equal to this data and have this size :

First call (Data in hexadecimal with 10 bytes) enter image description here

And Second call (Data in hexadecimal with 2 bytes) enter image description here

This is how i use the recvfrom function (t->sock is the socket fd of the server, t->msg_recv is the buffer created to receive the msg from the servern and t->_recv is the sockaddr* struct for the receive):

if (recvfrom(t->sock, t->msg_recv, sizeof(t->msg_recv), 0, \
    (struct sockaddr *)&t->_recv, \
    (socklen_t[1]){sizeof(struct sockaddr_in)}) < 0) {
        perror("recvto()");
        exit(84);
    }

Barmar here is the output of the Wireshark message send :

enter image description here

Here is the code of send and recvfrom on the same function :

int len = 0;
    if (sendto(t->sock, t->buffer, t->ip->tot_len, 0,
               (struct sockaddr *)&t->_sin, sizeof(t->_sin)) < 0) {
      perror("sendto()");
      exit(84);
    }
    if ((len = recvfrom(t->sock, t->msg_recv, sizeof(t->msg_recv), 0, \
    (struct sockaddr *)&t->_recv, \
    (socklen_t[1]){sizeof(struct sockaddr_in)})) < 0) {
        perror("recvto()");
        exit(84);
    }
Zahreddine Laidi
  • 560
  • 1
  • 7
  • 20
  • 1
    Why do you have backslashes at the end of the lines? C doesn't require that except in macros. – Barmar Apr 26 '19 at 21:52
  • 1
    How do you know the client isn't receiving the right information? – Barmar Apr 26 '19 at 21:55
  • Where do you set `len_buffer`? – Barmar Apr 26 '19 at 21:57
  • Because the right information is the information in the Wireshark, the hexadecimal message with a length of 10, but i only receive a E with a size of 2 @Barmar – Zahreddine Laidi Apr 26 '19 at 21:59
  • The len_buffer is set my my.h, the size is set to 256 like `msg_recv[256]` in the t struct. – Zahreddine Laidi Apr 26 '19 at 22:00
  • The backslashes are useless, just to be more clearer for me.. – Zahreddine Laidi Apr 26 '19 at 22:02
  • 2
    What do you mean by "I only receive a E with a size of 2"? `recvfrom()` returns the length of the packet, but you don't assign that anywhere. – Barmar Apr 26 '19 at 22:02
  • @ZahreddineLaidi Can you capture the response of your server in Wireshark, what is actually on the wire that the server is sending? – user3469811 Apr 26 '19 at 22:04
  • 1
    Are you trying to print the buffer as a string? It's not a string, it's binary data. `E` is the `45` byte at the end of the first row of the hex, and there's a zero byte after it. Since you're using a raw socket, you get the IP and UDP headers in the buffer. – Barmar Apr 26 '19 at 22:06
  • Yes i'm trying to print the buffer as a string, but what can i do to have the same resulat like the Wireshark when i print it ? @Barmar – Zahreddine Laidi Apr 26 '19 at 22:09
  • The two screen wireshark are the response sended by my server at the two calls. @user3469811 – Zahreddine Laidi Apr 26 '19 at 22:10
  • use a loop to print hex bytes. – Barmar Apr 26 '19 at 22:10
  • And it will solve my problem ? because i already converted the string in hex bytes but it print me the E in hexa... so how can i do this ?? @Barmar – Zahreddine Laidi Apr 26 '19 at 22:15
  • can you post the codeline that prints out `buffer = [E] | len_buffer = [2]`, and what you expect the output to be on stdout – user3469811 Apr 26 '19 at 22:20
  • I do this just after my recvfrom : `printf("buffer = [%s] | len_buffer = [%d]\n", t->msg_recv, strlen(t->msg_recv));` And for my final stdout, i want to have the blue colored Data like in the wireshark. @user3469811 – Zahreddine Laidi Apr 26 '19 at 22:23
  • `strlen` returns a `size_t`, not an `int`. The correct format specifier is `%zu`, not `%d`. – melpomene Apr 26 '19 at 22:25

1 Answers1

0

The buffer is not a string, it's binary data, so you shouldn't print it with %s.

You need to get the length of the buffer when you call recvfrom. Then use a loop that prints each byte with %02X format.

len = recvfrom(t->sock, t->msg_recv, sizeof(t->msg_recv), 0, \
    (struct sockaddr *)&t->_recv, \
    (socklen_t[1]){sizeof(struct sockaddr_in)});
if (len < 0) {
        perror("recvto()");
        exit(84);
}
for (int i = 0; i < len; i ++) {
    printf("%02X ", t->msg_recv[i]);
    if (i % 16 == 15) {
        printf("\n");
    } else if (i % 16 == 7) {
        printf(" ");
    }
}
printf("\n");
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • `%X` expects an unsigned int, so you may have to use a cast there. – melpomene Apr 26 '19 at 22:30
  • Is it normal ? my len, so the return of the recvfrom is always equal to 0. Why ? @Barmar – Zahreddine Laidi Apr 26 '19 at 22:30
  • @ZahreddineLaidi A return value of 0 means "end of file"; in the case of sockets, this means the write end on the other side has disconnected. Alternatively it could mean you got the code wrong; check your parentheses. – melpomene Apr 26 '19 at 22:32
  • @ZahreddineLaidi Make sure you added the parentheses correctly around the assignment in the `if` statement. It's a common mistake. If you don't do it correctly, you set `len` to the result of `<`. – Barmar Apr 26 '19 at 22:34
  • I've split the assignment into a separate statement to make it clearer. – Barmar Apr 26 '19 at 22:36
  • What is this: `(socklen_t[1]){sizeof(struct sockaddr_in)}`? Is this a new C11 syntax I don't know about? – Barmar Apr 26 '19 at 22:37
  • @Barmar It's a very new feature: Compound literals. It's only 20 years old (see C99, 6.5.2.5). – melpomene Apr 26 '19 at 22:38
  • By the way it worked, but this is the message that i have sent and not the message returned by the server, so this is not what i needed.. @Barmar – Zahreddine Laidi Apr 26 '19 at 22:38
  • @melpomene Thanks. I'm not really a professional C programmer, I just play one on SO. – Barmar Apr 26 '19 at 22:39
  • @ZahreddineLaidi That makes no sense. `recvfrom` won't return a message you sent, it only returns a message that was received. – Barmar Apr 26 '19 at 22:41
  • But this is the output that i got and the Wireshark with the first message send : `len = 40 || hex : 45 10 00 28 24 FFFFFFB9 00 00 40 11 57 FFFFFFFA 7F 00 00 01 7F 00 00 01 1F FFFFFF90 11 FFFFFFC1 00 14 00 00 63 6C 69 65 6E 74 20 68 65 6C 6C 6F ` and the Wireshark : (i added the img at the end of the subject) @Barmar – Zahreddine Laidi Apr 26 '19 at 22:45
  • What kind of socket is this? Is it a packet capturing socket? Then it will return both sent and received packets, but they have to match your filtering specification. Maybe your filter only matches the packets you're sending. – Barmar Apr 26 '19 at 22:47
  • You've left out so much important information from the question. – Barmar Apr 26 '19 at 22:47
  • Here is the socket : `t->sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);` – Zahreddine Laidi Apr 26 '19 at 22:49
  • Then I really can't explain why this code on the client is showing the message it sent instead of what it received from the server. – Barmar Apr 26 '19 at 22:52
  • I send and recvfrom in the same function, i putted the code in the end of my subject @Barmar – Zahreddine Laidi Apr 26 '19 at 22:56
  • That shouldn't be a problem, since my code is only printing `t->msg_recv`, not `t->buffer`. – Barmar Apr 26 '19 at 22:57
  • True, and i really dont understand why.. :( – Zahreddine Laidi Apr 26 '19 at 22:59