C

socket bind() errno 22 - 沒有時間等待套接字

  • March 15, 2021

我對 C 和 Linux 很陌生,我嘗試設置一個 TCP 套接字伺服器,用於與我在 Ubuntu 系統上編譯和執行的 C 程式碼進行數據交換。

從教程中,我複制了以下程式碼(見下文),它可以啟動伺服器並使用客戶端程式碼(在同一台機器上用於測試目的)接收數據(時間和日期)。

然後我重新啟動了 Ubuntu 機器,從那以後我不能再啟動伺服器了。

然後我在下面的程式碼中添加了異常處理,它拋出“無法綁定”錯誤號 22,這意味著“無效參數”?這對我來說沒有意義,因為相同的程式碼以前工作得很好。

我假設“舊”套接字處於時間等待狀態或尚未關閉,但我檢查了所有不同狀態的“ss -all state xxx”連接,一切似乎都很好。

還嘗試使用不同的埠和程式碼 - 同樣的問題。

希望任何人都可以幫助我解決這個問題,因為我不知道還能嘗試什麼。

// C-Code Server
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h> 

int main(int argc, char *argv[])
{

   int listenfd = 0, connfd = 0;
   struct sockaddr_in serv_addr; 

   char sendBuff[1025];
   time_t ticks; 

   //Open a socket
   listenfd = socket(AF_INET, SOCK_STREAM, 0);
   memset(&serv_addr, '0', sizeof(serv_addr));
   memset(sendBuff, '0', sizeof(sendBuff)); 
   if (listenfd == -1) {
       printf("Error: unable to open a socket\n");
       exit(1);
   }

   //Create an Adress
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_addr.s_addr = htons(INADDR_ANY);
   serv_addr.sin_port = htons(1234); 


   //Macht schon benutzte Adresse mit SO_REUSEADDR nutzbar
   int opt = 1;
   if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt))<0) {
       perror("setsockopt");exit(EXIT_FAILURE);
   }
   if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(opt))<0)   {
       perror("setsockopt");exit(EXIT_FAILURE);
   }


   bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); 

   if ((bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) == -1) {
       printf("Error: unable to bind\n");
       printf("Error code: %d\n", errno);
       exit(1);
   }



   listen(listenfd, 10); 

   while(1)
   {
       connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 

       if (connfd == -1) {
           printf("Error: unable to accept connections\n");
           printf("Error code: %d\n", errno);
           exit(1);
       }



       ticks = time(NULL);
       snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
       write(connfd, sendBuff, strlen(sendBuff)); 

       close(connfd);
       sleep(1);
    } 
}

bind(2)告訴:

EINVAL The socket is already bound to an address.

實際上,您在同一個套接字上呼叫了兩次 bind() :

    bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); 

    if ((bind(listenfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) == -1) {
        printf("Error: unable to bind\n");
        printf("Error code: %d\n", errno);
        exit(1);
    }

刪除第一個 bind() 後,我可以在連接時收到日期。

引用自:https://unix.stackexchange.com/questions/548282