在C中通过套接字传输整数

Mag*_*gie 8 c sockets int

int在C中传输套接字的适当方法是什么?
到目前为止我所做的是:

int n = 4;
int tmp = htonl(n);
write(socket, &tmp, sizeof(tmp));
Run Code Online (Sandbox Code Playgroud)

int tmp,n;
read(socket, &tmp, sizeof(tmp));
n = ntohl(tmp);
Run Code Online (Sandbox Code Playgroud)

但是,收到的整数有时为0.并非总是如此,而是说5次中的2次.它永远不会是其他值,为什么?

更新:读取的返回值为-1,错误为:

Resource temporarily unavailable
Run Code Online (Sandbox Code Playgroud)

Bor*_*sko 11

首先,sizeof(int)您的发送方和接收方机器可能会有所不同.所以我建议你使用像int32_tfrom 这样的东西stdint.h.

此外,不能保证read(..,..,sizeof(int))读取确切的sizeof(int)字节 - 它什么都不读,或者它可以读取更少的字节.所以,正确的变体将是更像这样的东西:

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;
}
Run Code Online (Sandbox Code Playgroud)


iPa*_*rJr 10

这应该没有任何问题,试试这个:

在发件人(服务器)端:

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));
Run Code Online (Sandbox Code Playgroud)

在接收方(客户端)方面:

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
}
Run Code Online (Sandbox Code Playgroud)

希望这会有所帮助.

  • 但这不处理部分读取或写入!read 一次可以返回一个字节的结果。 (4认同)
  • 这应该是公认的答案!谢谢!`htonl` 和 `ntohl` +1 (2认同)
  • @D.Shawley 你是对的。这个答案与问题有同样的问题,但没有解决任何问题。因此你应该否决它。 (2认同)