0

我有以下代码:

if ( ( m_mainSocket = ::socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ) ) < 0 )
{
    throw Exception( __FILE__, __LINE__ ) << "Unable to create socket";
}

int on( 0 );

if ( setsockopt( m_mainSocket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof( on ) ) )
{
    throw Exception( __FILE__, __LINE__ ) << "Can't make server socket resusable.";
}

sockaddr_in addr;
memset( &addr, 0, sizeof( addr ) );

addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl( INADDR_ANY );
addr.sin_port = htons( p_localPort );

if ( ::bind( m_mainSocket, reinterpret_cast< sockaddr * >( &addr ), sizeof( addr ) ) < 0 )
{
    throw Exception( __FILE__, __LINE__ ) << "Failed to bind the server socket";
}

当我用 close() 关闭服务器时,我无法在同一个端口再次打开服务器。为什么?我需要更改端口或重新启动系统。它只发生在 Ubuntu 和 MacOSX 中。在 Windows 中我没有这个问题。

错误发生在 ::bind() 函数中。它不允许我重新绑定()一个套接字两次。

如何重新绑定?

4

1 回答 1

4

您需要将 1 而不是 0 传递给 REUSEADDR。

socket(7)手册页:

   套接字选项
       可以使用 setsockopt(2) 设置这些套接字选项并使用
       将所有套接字的套接字级别设置为 SOL_SOCKET 的 getsockopt(2):

      ……

       SO_REUSEADDR
              指示用于验证提供的地址的规则
              在 bind(2) 调用中应该允许重用本地地址。为了
              AF_INET sockets 这意味着一个socket可以绑定,除非当
              有一个活动的侦听套接字绑定到该地址。什么时候
              监听套接字绑定到具有特定端口的 INADDR_ANY
              那么任何本地都无法绑定到此端口
              地址。参数是一个整数布尔标志。
于 2010-02-02T19:18:44.423 回答