能否给个 send 和 recv 的例子
要求能处理常见的 errno ,如:EAGAIN, EINTR
当接受到的数据大小 n > BUF_SIZE 时,能够正确处理
1
ohwind 2023-05-09 14:35:24 +08:00
By ChatGPT:
下面是一个使用 POSIX 网络编程的 send() 和 recv() 函数的例子,可以处理常见的错误和当接受到的数据大小大于缓冲区大小时的情况: ``` #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <errno.h> #include <string.h> #include <stdio.h> #define BUF_SIZE 1024 void handle_error(const char *msg) { fprintf(stderr, "%s: %s\n", msg, strerror(errno)); exit(EXIT_FAILURE); } void send_data(int sockfd, const char *data, size_t len) { size_t total_sent = 0; while (total_sent < len) { ssize_t n = send(sockfd, data + total_sent, len - total_sent, 0); if (n < 0) { if (errno == EAGAIN || errno == EINTR) { continue; } else { handle_error("send error"); } } total_sent += n; } } void recv_data(int sockfd) { char buf[BUF_SIZE]; ssize_t n; while ((n = recv(sockfd, buf, sizeof(buf), 0)) > 0) { // handle received data if (n > BUF_SIZE) { fprintf(stderr, "received data too large: %zd\n", n); exit(EXIT_FAILURE); } } if (n < 0) { if (errno == EAGAIN || errno == EINTR) { // try again later return; } else { handle_error("recv error"); } } // n == 0 means the other end closed the connection printf("connection closed by peer\n"); exit(EXIT_SUCCESS); } ``` 在 send_data() 函数中,我们使用一个循环来确保将所有数据都发送出去。如果 send() 函数返回一个负值,我们首先检查错误码是否为 EAGAIN 或 EINTR ,如果是,则继续循环以重新尝试发送数据。否则,我们假定出现了其他错误并调用 handle_error() 函数来处理它。 在 recv_data() 函数中,我们使用一个循环来反复接收数据,直到 recv() 函数返回一个小于或等于零的值,这表示连接已关闭或出现错误。如果 recv() 函数返回一个负值,我们首先检查错误码是否为 EAGAIN 或 EINTR ,如果是,则说明暂时无法接收数据,可以稍后再尝试。如果出现其他错误,则调用 handle_error() 函数处理它。如果接收到的数据的大小大于缓冲区大小,则输出错误消息并退出程序。 |