c - 在 C 中为套接字编写 send_all 和 recv_all 函数

标签 c sockets io

我是一个新的 C 程序员,所以你必须原谅我缺乏知识。我正在尝试在 Windows 机器上使用 C 中的套接字在客户端和服务器之间来回发送数据。我将 cygwin 的工具与 codeblocks IDE 一起使用。简单的发送和接收不起作用,所以经过一番搜索后,我的印象是我的问题是我需要一个 send_all 和 recv_all 函数。我已经编写了以下两个函数,但接收似乎总是陷入无限循环。我不太确定为什么。

void send_all(int socket, void *buffer, int length) {
    size_t i = 0;
    for (i = 0; i < length; i += send(socket, buffer, length - i, 0)){
        printf("Completed: %d bytes \r", i);
    }
    printf("Send Completed: %d bytes \n", length);
}

void recv_all(int sockfd, void *buffer, int length){
    size_t i = 0;
    for (i = 0; i < length; i+= recv(sockfd, buffer + i, length - i, 0)){
        printf("Completed: %d bytes \r", i);
    }
    printf("Receive Completed: %d bytes \n", length);
}

我想知道是不是因为接收方不知道发送方发送了多少字节。感谢所有建议,但请保持建设性。谢谢。

最佳答案

recv() 实际上返回一个 signed 值(int 在 Winsock 中,ssize_t 在 POSIX 中)。如果发生读取错误,或者如果套接字处于非阻塞模式且没有数据可用,则其返回值可以是负数。如果套接字被优雅地关闭,它的返回值为零(这会导致代码中的无限循环)。

在将返回值添加到字节计数器之前,您需要检查返回值,以检测这两种情况。

如果您的套接字处于阻塞模式(默认),您的代码将无限期阻塞,直到收到所需的数据量,或者发生错误(一旦您添加代码来检查)。鉴于您的函数名称,这似乎是您想要的行为。如果是这样,您的一般方法是合理的。

ssize_t bytesRead = 0;

while (bytesRead < length)
{
    ssize_t rv = recv(/* ... */);

    if (rv == 0)
    {
        printf("Socket closed gracefully before enough data received\n");
        break;
    }

    else if (rv < 0)
    {
        // if your socket is non-blocking, check for EAGAIN which
        // would mean no data is currently available; in this case you
        // could do something like call select() on the socket to
        // go to sleep until more data comes in

        printf("Read error occurred before enough data received\n");
        break;
    }

    bytesRead += rv;
}

关于c - 在 C 中为套接字编写 send_all 和 recv_all 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21861279/

相关文章:

c - "fread"导致段错误的函数

C套接字recv()错误处理

sockets - socketio4net-代理问题

java - 尝试与 Web 服务通信时遇到 "No route to host"错误

c - 如何读取文件直到C中的一个字符

c - 如何在 C 中将 double 据类型可移植地写入文件

Const 不就是 const 吗?

c - Linux c 编程引用

javascript - Sockets.io 接收但不发送消息

linux - RCHAR 是否包含 READ_BYTES (proc/<pid>/io)?