Pass an integer through a socket in C

How can I pass an int through a socket in C?
What am I doing so far:

 int n = 4; int tmp = htonl(n); write(socket, &tmp, sizeof(tmp)); 

and

 int tmp,n; read(socket, &tmp, sizeof(tmp)); n = ntohl(tmp); 

However, an integer is sometimes obtained 0. Not always, but let them speak 2 out of 5 times. It is never some other value, always 0. Why?

UPDATE: the return value from read is -1, and the error is:

 Resource temporarily unavailable 
+6
source share
3 answers

First of all, sizeof(int) may differ on your machine sender and receiver. Therefore, I would recommend you use something like int32_t from stdint.h .

In addition, it is not guaranteed that read(..,..,sizeof(int)) will accurately read sizeof(int) bytes - it cannot read anything or can read less bytes. So, the correct option would be something like this:

 int send_int(int num, int fd) { int32_t conv = htonl(num); char *data = (char*)&conv; int left = sizeof(conv); int rc; do { rc = write(fd, data, left); if (rc < 0) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { // use select() or epoll() to wait for the socket to be writable again } else if (errno != EINTR) { return -1; } } else { data += rc; left -= rc; } } while (left > 0); return 0; } int receive_int(int *num, int fd) { int32_t ret; char *data = (char*)&ret; int left = sizeof(ret); int rc; do { rc = read(fd, data, left); if (rc <= 0) { /* instead of ret */ if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { // use select() or epoll() to wait for the socket to be readable again } else if (errno != EINTR) { return -1; } } else { data += rc; left -= rc; } } while (left > 0); *num = ntohl(ret); return 0; } 
+8
source

This should work without any problems, try the following:

On the sender (server) side:

 int number_to_send = 10000; // Put your value int converted_number = htonl(number_to_send); // Write the number to the opened socket write(client_socket, &converted_number, sizeof(converted_number)); 

On the receiver side (client):

 int received_int = 0; return_status = read(client_socket, &received_int, sizeof(received_int)); if (return_status > 0) { fprintf(stdout, "Received int = %d\n", ntohl(received_int)); } else { // Handling erros here } 

Hope this helps.

+7
source

Since no one mentioned sprintf

you can just convert any variable to char* with it and send

 if(strcmp(buf,"movUP") == 0) { char* msg = calloc(1, 20); pos.y += 0.0001f; sprintf(msg,"NEW::POS::Y=%.4f", pos.y); sendto(master, msg, 20, 0, (struct sockaddr*)&client, addrlen); } 

Test

 movUP NEW::POS::Y=0.0001 movUP NEW::POS::Y=0.0002 movUP NEW::POS::Y=0.0003 movUP NEW::POS::Y=0.0004 

Use %d for integers, %f for floats

to convert back to integer, use atoi(char*)
to convert back to float, use atof(char*)

before conversion, be sure to use strstr() to get the float value only starting at "0"

  float myPos; // floating variable that stores Object Position in the World ... .... memset(buf, 0, MAXBUFFER); // clears the previous buffer recvfrom(master, buf, MAXBUFFER, 0, (struct sockaddr*)&server, &addrlen); char* newY = strstr(buf, "0");// NEW::POS::Y=0.0001 --->> 0.000100 myPos = atof(newY); // new object position by the server printf("My New Position is %.4f\n", myPos); // Out: My New Position is 0.0011 -> 0.0012 -> 0.0013 -> 0.0014. 

For integers ( not ) you can use the same technique and just multiply it by

 float f = 0.000002f; // that is supposed to be 2 integer value int i = (int)(f*1000000); // now, i = 2 

the above methods are fully protected

If you want a harder conversion, you can use strncpy or memcpy and cut the line starting at the given index with some length, assuming you already know the incoming buffer, but in my personal view I really recommend this, especially on socketless connections like this one, a lot of computation and calls for the length of the buffer. It’s not easy to debug sometimes if you are not fully aware of what you are doing.

Note 1 Be careful with non - zeros in the buffer when you are waiting for the server to move / position or whatever if you plan to use the 1st method.

Note 2 You can just send an integer or float , convert it and versa without having to cut or multiply .

Let new game network developers find this answer useful, since we cannot send or receive except char* with UDP sendto (), recvfrom ().

+1
source

Source: https://habr.com/ru/post/907641/


All Articles