当前位置: 首页 > 知识库问答 >
问题:

什么会导致sock send()命令上的“资源暂时不可用”

李胡媚
2023-03-14

什么会导致套接字send()命令上的资源暂时不可用错误?套接字设置为af_unix,sock_stream。它大部分时间都在工作,但偶尔会得到这个错误。插座的接收端似乎工作正常。

我知道这不是很详细,但我只是在寻找大致的想法。谢了!

共有1个答案

邵飞白
2023-03-14

让我举个例子:

>

  • 客户端连接到服务器,每1秒向服务器发送1MB数据。

    服务器端接受一个连接,然后Hibernate20秒,没有来自客户端的recv消息,因此客户端中的TCP发送缓冲区将满。

    客户端中的代码:

    #include <arpa/inet.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <string.h>
    #define exit_if(r, ...)                                                                          \
        if (r) {                                                                                     \
            printf(__VA_ARGS__);                                                                     \
            printf("%s:%d error no: %d error msg %s\n", __FILE__, __LINE__, errno, strerror(errno)); \
            exit(1);                                                                                 \
        }
    
    void setNonBlock(int fd) {
        int flags = fcntl(fd, F_GETFL, 0);
        exit_if(flags < 0, "fcntl failed");
        int r = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
        exit_if(r < 0, "fcntl failed");
    }
    
    void test_full_sock_buf_1(){
        short port = 8000;
        struct sockaddr_in addr;
        memset(&addr, 0, sizeof addr);
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = INADDR_ANY;
    
    
        int fd = socket(AF_INET, SOCK_STREAM, 0);
        exit_if(fd<0, "create socket error");
    
        int ret = connect(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr));
        exit_if(ret<0, "connect to server error");
        setNonBlock(fd);
    
        printf("connect to server success");
    
        const int LEN = 1024 * 1000;
        char msg[LEN];  // 1MB data
        memset(msg, 'a', LEN);
    
        for (int i = 0; i < 1000; ++i) {
            int len = send(fd, msg, LEN, 0);
            printf("send: %d, erron: %d, %s \n", len, errno, strerror(errno));
            sleep(1);
        }
    
    }
    
    int main(){
        test_full_sock_buf_1();
    
        return 0;
    }
    

    服务器端的代码:

        #include <arpa/inet.h>
        #include <sys/socket.h>
        #include <stdio.h>
        #include <errno.h>
        #include <fcntl.h>
        #include <stdlib.h>
        #include <string.h>
        #define exit_if(r, ...)                                                                          \
            if (r) {                                                                                     \
                printf(__VA_ARGS__);                                                                     \
                printf("%s:%d error no: %d error msg %s\n", __FILE__, __LINE__, errno, strerror(errno)); \
                exit(1);                                                                                 \
            }
    void test_full_sock_buf_1(){
    
        int listenfd = socket(AF_INET, SOCK_STREAM, 0);
        exit_if(listenfd<0, "create socket error");
    
        short port = 8000;
        struct sockaddr_in addr;
        memset(&addr, 0, sizeof addr);
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = INADDR_ANY;
    
        int r = ::bind(listenfd, (struct sockaddr *) &addr, sizeof(struct sockaddr));
        exit_if(r<0, "bind socket error");
    
        r = listen(listenfd, 100);
        exit_if(r<0, "listen socket error");
    
        struct sockaddr_in raddr;
        socklen_t rsz = sizeof(raddr);
        int cfd = accept(listenfd, (struct sockaddr *) &raddr, &rsz);
        exit_if(cfd<0, "accept socket error");
    
        sockaddr_in peer;
        socklen_t alen = sizeof(peer);
        getpeername(cfd, (sockaddr *) &peer, &alen);
    
        printf("accept a connection from %s:%d\n", inet_ntoa(peer.sin_addr), ntohs(peer.sin_port));
    
        printf("but now I will sleep 15 second, then exit");
        sleep(15);
    }
    

    启动服务器端,然后启动客户端。

    服务器端可以输出:

    accept a connection from 127.0.0.1:35764
    but now I will sleep 15 second, then exit
    Process finished with exit code 0
    

    客户端可以输出:

    connect to server successsend: 1024000, erron: 0, Success 
    send: 1024000, erron: 0, Success 
    send: 1024000, erron: 0, Success 
    send: 552190, erron: 0, Success 
    send: -1, erron: 11, Resource temporarily unavailable 
    send: -1, erron: 11, Resource temporarily unavailable 
    send: -1, erron: 11, Resource temporarily unavailable 
    send: -1, erron: 11, Resource temporarily unavailable 
    send: -1, erron: 11, Resource temporarily unavailable 
    send: -1, erron: 11, Resource temporarily unavailable 
    send: -1, erron: 11, Resource temporarily unavailable 
    send: -1, erron: 11, Resource temporarily unavailable 
    send: -1, erron: 11, Resource temporarily unavailable 
    send: -1, erron: 11, Resource temporarily unavailable 
    send: -1, erron: 11, Resource temporarily unavailable 
    send: -1, erron: 104, Connection reset by peer 
    send: -1, erron: 32, Broken pipe 
    send: -1, erron: 32, Broken pipe 
    send: -1, erron: 32, Broken pipe 
    send: -1, erron: 32, Broken pipe 
    send: -1, erron: 32, Broken pipe 
    

    您可以看到,由于服务器端不从客户端收回数据,所以当客户端TCP缓冲区已满时,但您仍然发送数据,因此可能会出现资源暂时不可用错误。

  •  类似资料:
    • 问题内容: 什么会导致套接字命令出错?套接字设置为。它在大多数时间都有效,但偶尔会出现此错误。插槽的接收端似乎工作正常。 我知道这不是很详细,但我只是在寻找一般想法。谢谢! 问题答案: 是与相对应的错误消息,这意味着该操作将被阻止,但请求了非阻止操作。对于,这可能是由于以下原因之一: 显式地将文件描述符标记为非阻塞;要么 将旗帜传递给; 要么 使用套接字选项设置发送超时。

    • 我在C中使用tcp套接字服务器和客户端。使用AF_INET、SOCK_STREAM和IPPROTO_TCP 在sock send()命令上有一个可能导致“资源暂时不可用”的帖子,其中Davide Berra说 这是因为您使用的是非阻塞套接字,并且输出缓冲区已满。 从send()手册页

    • 问题内容: 如果您查看Node.js 文档开头的域,则会指出: 本质上,throw在JavaScript中是如何工作的,几乎没有任何方法可以安全地“从上次中断的地方捡起”,而不会泄漏引用或创建其他未定义的脆性状态。 再次在代码示例中,它在第一部分中给出: 尽管我们阻止了进程的突然重启,但是我们正在疯狂泄漏资源 我想了解为什么会这样?哪些资源正在泄漏?他们建议您仅使用域来捕获错误并安全地关闭进程。这

    • res\drawable\mylayerlistdrawable.xml ----------------------------------------------------------------------------------- 最终答案 在api 21之前的xml可提取资源中,我们不能使用?attr。由aapt在编译时创建的可提取资源。运行时用于动态连接的Attr资源。 解决方案是为

    • 创建套接字 使其非阻塞 呼叫连接 按预期返回-1和errno EINPROGRESS 调用select 返回>0,因此已建立连接 再次阻塞套接字 此部件的代码如下: 那还行。但是我有一个循环,在这个循环中我调用了一个函数,该函数检查是否收到了要读取的新数据包: