What is the appropriate way to transfer an int
over a socket in C?
What I am doing so far is:
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, the integer received is sometimes 0. Not always, but let's say 2 out of 5 times. It is never some other value, always 0. Why?
UPDATE: Return value from read is -1 and an error is:
Resource temporarily unavailable
tcpsocket. send(num) accept a string , link to the api, so don't convert the number you insert to int . Show activity on this post. If you send the number 11 and then immediately send 12, how will the receiver know whether you sent two numbers: 11 and 12 or one number: 1112?
DESCRIPTION. The socket() function shall create an unbound socket in a communications domain, and return a file descriptor that can be used in later function calls that operate on sockets. The socket() function takes the following arguments: domain. Specifies the communications domain in which a socket is to be created ...
All that matters in your code is that the number represents a specific file or socket. The integer that's returned by socket() is a file descriptor, i.e. a value that refers to a specific FILE data structure.
You can send and recv from any connected socket. The direction of the data flow does not have anything to do with the client/server relationship. It is very common for clients and servers to both send and receive.
First of all, sizeof(int)
may differ on your sender and receiver machine. So I would recommend you to use something like int32_t
from stdint.h
.
Also, it is not guaranteed that read(..,..,sizeof(int))
will read exactly sizeof(int)
bytes - it can read nothing, or it can read less bytes. So, the correct variant will be something more 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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With