对等连接重置-Winsock

佩德罗·马丁斯(Pedro Martins)

我知道“对等连接重置”是什么意思,并且可能已经回答了,但是我很抱歉。

我正在使用TCP制作客户端和服务器,当运行良好时,服务器应该为24/7,但是当我关闭客户端时,由于“对等重置连接”,发送和接收失败。好的,但是问题在于服务器完全挂起,仅允许客户端连接并且不与send / recv通信,我不假装总是重新启动服务器。

这是我正在使用的源代码:

客户:

bool Browsify::Connect( const char* addr, unsigned short port )
{
    if(!net.isInitialized)
    {
        Log::Error( "Browsify wasn't initialized." );
        return false;
    }

    net.addr = addr;
    net.port = port;

    net.s = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

    if(res == INVALID_SOCKET)
    {
        Log::Error( "socket() failed - %d.", WSAGetLastError() );
        return false;
    }

    sockaddr_in sk;
    memset( (char*) &sk, 0, sizeof(sk) );

    sk.sin_addr.s_addr = inet_addr( addr );
    sk.sin_port = htons( port );
    sk.sin_family = AF_INET;

    res = connect( net.s, (sockaddr*) &sk, sizeof(sk) );

    if(res == SOCKET_ERROR)
    {
        Log::Error( "connect() failed - %d.", WSAGetLastError() );
        return false;
    }

    net.isConnected = true;

    CreateThread( NULL, NULL, (LPTHREAD_START_ROUTINE)
        Browsify::HandleReceive, NULL, NULL, NULL );

    return true;
}

ServerItem item[1024];

bool Browsify::HandleReceive()
{
    char buf[512];
    sprintf( buf, "getservers iw4" );
    res = send( net.s, buf, sizeof(buf), NULL );

    if(res == SOCKET_ERROR)
    {
        Log::Error( "send() failed - %d.", WSAGetLastError() );
        return false;
    }

    res = recv( net.s, (char*)&item, sizeof(item), NULL );

    if(res == SOCKET_ERROR)
    {
        Log::Error( "recv() failed - %d.", WSAGetLastError() );
        return false;
    }

    while(true)
    {
        if(res > NULL)
        {
            Browsify::QueryServer( 0 );
            // finally.. after thousands and thousands of years, I did it!
            // no winsock error, though, the server is really unstable.
            //Log::Info( "server count %d", item->serverCount );
        }
        else if(res == NULL)
        {
            Log::Warning( "Connection closed." );
        }

        Sleep( 1 );
    }

    return true;
}

服务器:

bool Browsify::Listen( uint16 port )
{
    printf( "# Listening on port %u...\n", port );

    if(!net.isInitialized)
    {
        printf( "ERROR: Browsify wasn't initialized.\n" );
        return false;
    }

    net.port = port;

    net.sListen = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

    if(net.sListen == INVALID_SOCKET)
    {
        printf( "ERROR: socket() failed - %d.\n", WSAGetLastError() );
        return false;
    }

    sockaddr_in sk;
    memset( (char*) &sk, 0, sizeof(sk) );

    sk.sin_addr.s_addr = ADDR_ANY;
    sk.sin_port = htons( port );
    sk.sin_family = AF_INET;

    res = bind( net.sListen, (sockaddr*) &sk, sizeof(sk) );

    if(res == SOCKET_ERROR)
    {
        printf( "ERROR: bind() failed - %d.\n", WSAGetLastError() );
        return false;
    }

    res = listen( net.sListen, SOMAXCONN );

    if(res == SOCKET_ERROR)
    {
        printf( "ERROR: listen() failed - %d\n", WSAGetLastError() );
        return false;
    }

    net.sClient = accept( net.sListen, NULL, NULL );

    if(net.sClient == INVALID_SOCKET)
    {
        printf( "ERROR: accept() failed - %d\n", WSAGetLastError() );
        return false;
    }
    else
    {
        printf( "# Unknown connection accepted.\n" );
    }

    closesocket( net.sListen );
    net.isListening = true;

    CreateThread( NULL, NULL, (LPTHREAD_START_ROUTINE)
        Browsify::HandleReceive, NULL, NULL, NULL );

    return true;
}

bool Browsify::HandleReceive()
{
    char recvbuf[1024];
    res = recv( net.sClient, recvbuf, sizeof(recvbuf), NULL );

    if(res == SOCKET_ERROR)
    {
        printf( "ERROR: recv() failed - %d.\n", WSAGetLastError() );
        closesocket( net.sClient );
        WSACleanup();
        //return false;
    }

    while(true)
    {
        if(res > NULL)
        {
            if(!strcmp( recvbuf, "getservers iw4" ))
            {
                ServerItem item[1024];

                strcpy( item[0].hostname, "^1PLAY^34^1FUN ^2TDM" );
                strcpy( item[0].mapname, "mp_rust" );
                strcpy( item[0].gametype, "war" );
                strcpy( item[0].addr, "127.0.0.1" );

                item[0].currPlayers = 1;
                item[0].maxPlayers = 18;
                item[0].port = 27005;

                strcpy( item[1].hostname, "^1PLAY^34^1FUN ^2ISNIPE" );
                strcpy( item[1].mapname, "mp_terminal" );
                strcpy( item[1].gametype, "iSnipe" );
                strcpy( item[1].addr, "127.0.0.1" );

                item[1].currPlayers = 15;
                item[1].maxPlayers = 18;
                item[1].port = 27005;

                item->serverCount = 2;

                res = send( net.sClient, (char*) &item, sizeof(item), NULL );

                if(res == SOCKET_ERROR)
                {
                    printf( "send() failed - %d\n", WSAGetLastError() );
                    closesocket( net.sClient );
                    WSACleanup();
                    //return false;
                }
            }
        }
        else if(res == NULL)
        {
            printf( "Connection closed.\n" );
        }

        Sleep( 1 );
    }

    shutdown( net.sClient, SD_SEND );

    return true;
}

这都是用于游戏的服务器浏览器的,这就是为什么它应该是24/7的原因。

罗德里戈

我认为问题是您打了listen()多次电话这不是服务器应该工作的方式。

进入服务器的正确方法是(伪代码):

SOCKET one_time_initialization()
{
    SOCKET listenSocket = socket(...);
    bind(listenSocket, ...);
    listen(listenSocket, ...);
    return listenSocket; //do not close the listensocket until the finishes!
}

void accept_connections(SOCKET listenSocket)
{
    for (;;) //or message driven, that depends on the application architecture
    {
        SOCKET socket = accept(listenSocket);
        //you should really create a structure/object here, add the socket in there
        //and create a thread passing the pointer to that structure as `lParam`
        Connection *data = new Connection(socket);

        CreateThread(NULL, NULL, HandleReceive, NULL, NULL, data);
        //the socket should be closed when the thread finishes and the data is deleted
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Winsock:连接套接字问题

来自分类Dev

HttpURLConnection错误(对等连接重置)

来自分类Dev

Docker,清漆,对等连接重置

来自分类Dev

Docker,清漆,对等连接重置

来自分类Dev

写入:对等方重置连接

来自分类Dev

Winsock是否限制并发连接数?

来自分类Dev

X时间后如何终止Winsock连接

来自分类Dev

Winsock无法连接到本地主机

来自分类Dev

Celery通过对等方重置连接

来自分类Dev

通过对等方重置MongoDB连接

来自分类Dev

MongoDB sureIndex:对等重置连接

来自分类Dev

通过对等呼叫soap Webservice重置连接

来自分类Dev

docker上的nginx:对等重置连接

来自分类Dev

Elasticsearch RestClient连接被对等方重置

来自分类Dev

使用sshfs由对等方重置连接

来自分类Dev

从nslcd读取错误:对等连接重置

来自分类Dev

Tomcat 7:对等连接或软件重置连接导致连接中止

来自分类Dev

对等方的TCP连接重置,并且传输端点未连接

来自分类Dev

在TCP套接字连接期间获取对等方重置的连接?

来自分类Dev

VB6 Winsock多个TCP连接> DoEvents问题

来自分类Dev

通过UDP winsock连接发送结构,结构大小?

来自分类Dev

Winsock的“连接”挂起。Visual Studio报告可能出现死锁

来自分类Dev

Winsock 客户端和服务器无法连接

来自分类Dev

SSH-对等重置连接-Linux主机

来自分类Dev

Python客户端错误“对等重置连接”

来自分类Dev

av_interleaved_write_frame():对等youtube重置连接。

来自分类Dev

Selenium WebDriver:socket.error:对等连接重置

来自分类Dev

java.net.SocketException:sendto失败:ECONNRESET(对等连接重置)

来自分类Dev

fopen():SSL:php中的对等错误重置连接

Related 相关文章

热门标签

归档