c++ - 只关闭一个套接字

标签 c++ sockets tcp

我制作了一个类似于套接字服务器的软件(在基础设施中的三个节点之间分发数据包)。 为简单起见,我创建了三个线程,一个用于每个 TCP 套接字(我知道这不是最佳选择,但就我的目的而言,这是最简单的选择,也是最快的),一切都运行良好。 在服务器启动时,三个套接字执行通常的初始化(getaddr、listen、bind 等)并监听三个不同的端口;当我启动客户端时,客户端正确连接并发送/接收数据。

问题是:每当一个客户端断开连接时,其他套接字也会被强行断开连接并重新启动,这有点问题。 我敢打赌可疑代码就在这里(这是从线程启动的例程):

void ManageSocket1( void )
{
    while( true )
    {
        Socket* socket = new Socket( 27016, "SocketName" );
        if( socket->CreateSocket() )
        {
            socket->StartCommunication();
        }
        socket->CloseSocket();
        delete socket;
    }
}

void ManageSocket2( void )
{
    // clone of ManageSocket1
}

CreateSocket() 负责创建套接字,而 StartCommunication() 接收/发送数据;对于这两种方法,无需发布代码,因为它是“通用”tcp 套接字打开代码。 ManageSocketX() 由 main() 中的线程启动,并且由于其性质而永远不会返回到 main()。

这是 CreateSocket():

int Socket::CreateSocket( void )
{
res = WSAStartup( MAKEWORD( 2,2 ), &wsaData );

if( res != 0 ) 
{
    logBook->PrintMsg( socketName, "WSAStartup failed" );
    return ERROR;
}
else
{
    logBook->PrintMsg( socketName, "WSAStartup done" );
}

res = getaddrinfo( NULL, socketPort, &hints, &result );

if ( res != 0 ) 
{
    logBook->PrintMsg( socketName, "GetAddrInfo failed" );
    WSACleanup();
    return ERROR;
}
else
{
    logBook->PrintMsg( socketName, "GetAddrInfo succesful");
}

ListenSocket = socket( result->ai_family, result->ai_socktype, result->ai_protocol );

if( ListenSocket == INVALID_SOCKET ) 
{
    logBook->PrintMsg( socketName, "GetAddrInfo failed with error: ", WSAGetLastError() );
    freeaddrinfo( result );
    WSACleanup();
    return ERROR;
}
else
{
    logBook->PrintMsg( socketName, "Socket created succesfully");
}

res = bind( ListenSocket, result->ai_addr, ( int )result->ai_addrlen );
if( res == SOCKET_ERROR ) 
{
    logBook->PrintMsg( socketName, "Bind failed with error: ", WSAGetLastError() );
    freeaddrinfo( result );
    closesocket( ListenSocket );
    WSACleanup();
    return ERROR;
}
else
{
    logBook->PrintMsg( socketName, "Socket successfully bound");
}

freeaddrinfo( result );

if( listen( ListenSocket, SOMAXCONN ) == SOCKET_ERROR ) 
{
    logBook->PrintMsg( socketName, "Bind failed with error: ", WSAGetLastError() );     
    closesocket( ListenSocket );
    WSACleanup();
    return ERROR;
}
else
{
    logBook->PrintMsg( socketName, "Listening on port", atoi( socketPort ) );
}

ClientSocket = accept( ListenSocket, NULL, NULL );
if( ClientSocket == INVALID_SOCKET ) 
{
    logBook->PrintMsg( socketName, "Accept failed:", WSAGetLastError() );
    closesocket( ListenSocket );
    WSACleanup();
    return 1;
}
else
{
    logBook->PrintMsg( socketName, "Client connection accepted" );
}

return SUCCESS;
}

那是 StartCom()

void Socket::StartCommunication( void )
{
char recvbuf[BUFLEN];
int  recvbuflen = BUFLEN;

do
{
    res = recv( ClientSocket, recvbuf, recvbuflen, 0 );
    if( res > 0 ) 
    {
        logBook->PrintMsg( socketName, "Bytes received:", res );            
    } 
    else if( res == 0 )
    {
        logBook->PrintMsg( socketName, "Connection closing..." );
    }
    else 
    {
        logBook->PrintMsg( socketName, "Receive failed:", WSAGetLastError() );
        closesocket( ClientSocket );
        WSACleanup();
        return;
    }       
} 
while( res > 0 );
}

最佳答案

问题是当任何套接字终止时,您正在调用 WSACleanup。来自文档:

In a multithreaded environment, WSACleanup terminates Windows Sockets operations for all threads.

进一步:

Sockets that were open when WSACleanup was called are reset and automatically deallocated as if closesocket were called.

关于c++ - 只关闭一个套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13891951/

相关文章:

Linux应用程序未ACK FIN数据包并发生重传

javascript - 通过javascript通过tcp ip发送命令

c++ - 多生产者消费者程序中不规则的打印语句

c++ - 双指针作为参数

java - 如何判断 java 日志记录套接字处理程序是否仍在运行?

c - 套接字客户端/服务器输入/输出轮询与 Linux 中的读/写

java - 如何检查连接是否是性能瓶颈

Java套接字TCP拆解

c++ - 赋值子表达式的求值顺序

java - Java/C++算法配置框架