2011-04-20 229 views
4

我遇到sendto問題。sendto:資源暫時不可用(errno 11)

我有一個接收方用recvfrom接收UPD數據包,然後用sendto回覆發送方。

不幸的是,我越來越errno 11(資源暫時不可用)。我正在使用兩個套接字。

第一個數據包實際發送,但不是那些算賬:

SENDTO ::成功

錯誤:0

SENDTO ::資源暫時不可用

錯誤:11。

sendto ::資源暫時不可用

...

這是我的代碼的摘錄:

int sockfd, sockSend; 

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 
      perror("socket"); 

    if ((sockSend = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 
      perror("socket"); 

    if (fcntl(sockfd, F_SETOWN, getpid()) < 0) { 
      perror("fcntl"); 
    } 
    if (fcntl(sockfd, F_SETFL, O_RDONLY | O_NONBLOCK | FASYNC) < 0) { 
      perror("fcntl"); 
    } 

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) 
        < 0) 
      perror("bind"); 

而在一個SIGIO處理程序:

len = sizeof(recv_addr); 
    char buffer[payload]; 
    bzero(buffer, payload); 
    n = recvfrom(sockfd, buffer, payload, MSG_DONTWAIT, (struct sockaddr *)&recv_addr, &len); 

    while (n > 0) { 

          sprintf(response, "%d\n%d\n%d\n", items, target_buf, pb_sp);   
          sendto(sockSend, response, strlen(response), 0, (struct sockaddr *) &recv_addr, sizeof(recv_addr)); 
          // sleep(1); 

          perror("sendto :"); 
          printf("error: %d.\n", errno); 

    } 

難道這個問題來,因爲港口仍然是熱的,我需要等待重用之前?我試圖改變港口,但它沒有幫助。

更新:如果睡眠(1)被註釋掉,那麼數據包實際上會發送!

非常感謝您的幫助。

+0

您使用的兩個插槽具有相同的端口?如果是這樣,原因是什麼? – penguin359 2011-04-20 22:47:36

+0

也許'SO_REUSEADDR'會有所幫助。或者您可以保持端口開放而不是打開和關閉端口,或者每次都可以使用新的隨機分配的端口號。 – 2011-04-20 22:52:02

+0

我已添加更多代碼。我有2個套接字,但只有一個綁定到一個端口(接收特定端口上的數據),另一個可以從任何端口發送數據。 – Jary 2011-04-20 22:53:31

回答

8

你所得到的錯誤:

EAGAIN or EWOULDBLOCK: The socket is marked nonblocking and the requested operation would block. POSIX.1-2001 allows either error to be returned for this case, and does not require these constants to have the same value, so a portable application should check for both possibilities.

您的插座設置爲非阻塞(O_NONBLOCK)。套接字仍然忙於發送前一條消息。直到第一個完成發送,您才能發送另一個。這就是爲什麼睡眠有幫助。

不要將它設置爲非阻塞,或者在select表示可以後再試。

+0

非常感謝。但O_NONBLOCK用於sockfd,不應該被sockSend阻塞(默認行爲)?我使用sockfd接收和sockSend發送數據。我刪除了fcntl()中的O_NONBLOCK,併發生相同的行爲。這就是你提到的,對吧? – Jary 2011-04-21 00:17:59

+0

通過刪除O_NONBLOCK和MSG_DONTWAIT,它結束了工作!非常非常感謝你!有沒有辦法阻止一個套接字(發送)和一個非阻塞(用於接收)? – Jary 2011-04-21 00:51:25

0

如果你必須設置套接字非阻塞,你可以放心地使用select做到這一點(只有):

select() and pselect() allow a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" for some class of I/O operation (e.g., input possible). A file descriptor is considered ready if it is possible to perform the corresponding I/O operation (e.g., read(2)) without blocking.

相關問題