【问题标题】:Is it possible to use the same port and ip address?是否可以使用相同的端口和IP地址?
【发布时间】:2014-02-14 03:28:13
【问题描述】:

我创建了一个 TCP 服务器程序,它绑定、侦听和接受来自特定 IP 地址和端口号的连接。 在第一次连接期间:服务器正在接受来自客户端的 SYN 数据包并将 ACK 发送回客户端。稍后从客户端获得 ACK。最后客户端是与服务器的 RST。

在第二次连接期间,客户端正在向从属发送一个 SYN 数据包,但没有来自服务器的 ACK。

我认为在第二次连接时不可能绑定相同的ip地址和端口号。

是否可以在第二次连接中绑定相同的ip地址和端口号?

服务器:

SOCKET sock;
    SOCKET fd;
uint16 port = 52428;

// I am also using non blocking mode

void CreateSocket()
{
   struct sockaddr_in server, client;  // creating a socket address structure: structure contains ip address and port number
  WORD wVersionRequested;
WSADATA wsaData;
int len;
int iResult;
u_long iMode = 1;

    printf("Initializing Winsock\n");


    wVersionRequested = MAKEWORD (1, 1);
    iResult =  WSAStartup (wVersionRequested, &wsaData);      
if (iResult != NO_ERROR)
  printf("Error at WSAStartup()\n"); 


    // create socket
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock < 0)    {
        printf("Could not Create Socket\n");
        //return 0;
    }

    printf("Socket Created\n");




    iResult = ioctlsocket(sock, FIONBIO, &iMode);
       if (iResult < 0)
        printf("\n ioctl failed \n");


    // create socket address of the server
    memset( &server, 0, sizeof(server));

    // IPv4 - connection
    server.sin_family = AF_INET;
    // accept connections from any ip adress
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    // set port
    server.sin_port = htons(52428);


    //Binding between the socket and ip address
    if(bind (sock, (struct sockaddr *)&server, sizeof(server)) < 0)
    {
        printf("Bind failed with error code: %d", WSAGetLastError());
    }

    //Listen to incoming connections
    if(listen(sock, 10) == -1){
        printf("Listen failed with error code: %d", WSAGetLastError());
    }

    printf("Server has been successfully set up - Waiting for incoming connections");

    for(;;){
        len = sizeof(client);
        fd = accept(sock, (struct sockaddr*) &client, &len);

        if (fd < 0){
            printf("Accept failed");
            closesocket(sock);
        }
        //echo(fd);
        printf("\n Process incoming connection from (%s , %d)", inet_ntoa(client.sin_addr),ntohs(client.sin_port));
//closesocket(fd);
    }

}

【问题讨论】:

  • 服务器是否关闭了它调用listen()的套接字?
  • 我会在上面添加我的代码。
  • 绑定什么?客户端套接字?您根本不需要绑定客户端套接字。

标签: sockets tcp ip port tcpserver


【解决方案1】:

TCP 连接由四个参数标识:

  • 本地 IP
  • 本地端口
  • 远程IP
  • 远程端口

服务器通常对其所有连接使用相同的本地 IP 和端口(例如,HTTP 服务器在端口 80 上侦听所有连接)。来自客户端的每个连接都将具有不同的远程 IP 和/或远程端口,这些解决了歧义。

当服务器关闭所有连接的套接字时,TCB 会在 TIME_WAIT 状态下停留几分钟。这通常会阻止进程绑定到端口,因为您无法绑定到具有任何关联 TCB 的本地 IP/端口。如果要重新启动服务器并绑定到它刚刚用于连接的相同端口和地址,则需要使用SO_REUSEADDR 套接字选项来解决这个问题。见:

Socket options SO_REUSEADDR and SO_REUSEPORT, how do they differ? Do they mean the same across all major operating systems?

了解详情。

【讨论】:

  • 我想在绑定调用之前使用 setsockopt 函数吗??
  • TIME_WAIT 状态仅在存在连接时发生。它与关闭监听套接字无关。
  • 谢谢,我已经添加了更多详细信息来解释为什么重新启动服务器时端口经常不可用。
  • 仍然令人困惑。现在您已经介绍了未定义的术语 TCB,但您还没有明确表示每个连接都有一个。也不是 TIME_WAIT 仅在存在 个连接时发生,这是最初的问题,也不是仅在发送第一个 FIN 的末尾发生。
  • 我知道,但我不会把这个答案变成对 TCP 是如何实现的完整解释。
猜你喜欢
  • 2021-12-11
  • 1970-01-01
  • 2019-11-20
  • 1970-01-01
  • 2019-08-11
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
相关资源
最近更新 更多