错误:10035 Winsock发送

时间:2018-07-27 00:55:41

标签: c++ c winsock

下午好,最近发现一个执行中的问题,正在生成错误10035,生成导致客户端连接不再是远程的且错误多次的错误,并且没有模拟器。与错误的相似性,我找不到解决方案,如果有人可以向我介绍如何解决此错误,我感谢。代码如下:

  

xxxx:发送软件包时发生错误。发送总数:500。错误:10035 xxxx:发送程序包时出错。要发送的总数:568。错误:10035

     BOOL CUser::SendMessageA(void)
{
    if(Socket.Socket <= 0)
    {
        Socket.nSendPosition = 0;
        Socket.nSentPosition = 0;

        return false;
    }

    if(Socket.nSentPosition > 0)
        RefreshSendBuffer();

    if(Socket.nSendPosition > MAX_BUFFER || Socket.nSendPosition < 0 || Socket.Socket < 0)
    {
        Log(SERVER_SIDE, LOG_ERROR, "Send, 1");

        return false;
    }

    if(Socket.nSentPosition > Socket.nSendPosition || Socket.nSentPosition > MAX_BUFFER || Socket.nSentPosition < 0)
    {
        Log(SERVER_SIDE, LOG_ERROR, "Send, 2");

        Socket.nSendPosition = 0;
        Socket.nSentPosition = 0;
    }

    INT32 err = 0;
    for(INT32 i = 0; i < 1; i++)
    {
        INT32 LOCAL_68 = Socket.nSendPosition - Socket.nSentPosition;

        INT32 LOCAL_69 = send(Socket.Socket, (char*)Socket.sendBuffer + Socket.nSentPosition, LOCAL_68, 0);
        if(LOCAL_69 != -1)
            Socket.nSentPosition += LOCAL_69;
        else
            err = WSAGetLastError();
    }

    if(err != 0)
    {
        CheckIdle(clientId);

        Socket.Error++;

        if(Socket.Error < 10)
            Log(clientId, LOG_INGAME, "Erro no envio do pacote. Total a ser enviado: %d. Error: %d", Socket.nSendPosition, err);
    }

    if(Socket.nSentPosition >= Socket.nSendPosition || err != 0)
    {
        Socket.nSendPosition = 0;
        Socket.nSentPosition = 0;

        return true;
    }

    if(Socket.nSendPosition > MAX_BUFFER)
        return false;

    return true;
}

我不知道是否可以撤消以下错误或某种类型的错误,因为当发生此错误时,它几乎立即会断开用户的连接,但仍保持连接状态。

1 个答案:

答案 0 :(得分:0)

错误10035为WSAWOULDBLOCK,这不是致命错误,但是您将其视为错误。

您显然正在使用 non-blocking 套接字,否则您一开始就不会遇到此“错误”。因此,您需要处理send() 可能无法阻塞调用线程的可能性(因为接收者没有足够的缓冲区空间来接收更多数据)。

只需再次重试相同的send()操作,最好在调用select()之前先等待它(以可选的超时时间),以等待接收器释放一些缓冲区空间后再发送数据。

尝试更多类似的方法:

BOOL CUser::SendMessageA(void)
{
    if (Socket.Socket == INVALID_SOCKET)
    {
        Socket.nSendPosition = 0;
        Socket.nSentPosition = 0;
        return FALSE;
    }

    if (Socket.nSentPosition > 0)
        RefreshSendBuffer();

    if (Socket.nSendPosition > MAX_BUFFER || Socket.nSendPosition < 0 || Socket.Socket == INVALID_SOCKET)
    {
        Log(SERVER_SIDE, LOG_ERROR, "Send, 1");
        return FALSE;
    }

    if (Socket.nSentPosition > Socket.nSendPosition || Socket.nSentPosition > MAX_BUFFER || Socket.nSentPosition < 0)
    {
        Log(SERVER_SIDE, LOG_ERROR, "Send, 2");
        Socket.nSendPosition = 0;
        Socket.nSentPosition = 0;
    }

    while (Socket.nSentPosition < Socket.nSendPosition) 
    {
        INT32 numSent = send(Socket.Socket, (char*)Socket.sendBuffer + Socket.nSentPosition, Socket.nSendPosition - Socket.nSentPosition, 0);
        if (numSent != SOCKET_ERROR)
            Socket.nSentPosition += numSent;
        else
        {
            INT32 err = WSAGetLastError();
            if (err != WSAWOULDBLOCK)
            {
                CheckIdle(clientId);
                Socket.Error++;
                if (Socket.Error < 10)
                    Log(clientId, LOG_INGAME, "Erro no envio do pacote. Total a ser enviado: %d. Error: %d", Socket.nSendPosition, err);
                return FALSE;
            }

            // optionally call select() here to wait for the socket to become writable again...
        }
    }

    Socket.nSendPosition = 0;
    Socket.nSentPosition = 0;
    return TRUE;
}

或者,如果您希望函数在发生阻塞时退出,而不是等待数据完全发送,而是在稍后的时间完成发送,则:

BOOL CUser::SendMessageA(void)
{
    if (Socket.Socket == INVALID_SOCKET)
    {
        Socket.nSendPosition = 0;
        Socket.nSentPosition = 0;
        return FALSE;
    }

    if (Socket.nSentPosition > 0)
        RefreshSendBuffer();

    if (Socket.nSendPosition > MAX_BUFFER || Socket.nSendPosition < 0 || Socket.Socket == INVALID_SOCKET)
    {
        Log(SERVER_SIDE, LOG_ERROR, "Send, 1");
        return FALSE;
    }

    if (Socket.nSentPosition > Socket.nSendPosition || Socket.nSentPosition > MAX_BUFFER || Socket.nSentPosition < 0)
    {
        Log(SERVER_SIDE, LOG_ERROR, "Send, 2");
        Socket.nSendPosition = 0;
        Socket.nSentPosition = 0;
    }

    INT32 numSent = send(Socket.Socket, (char*)Socket.sendBuffer + Socket.nSentPosition, Socket.nSendPosition - Socket.nSentPosition, 0);
    if (numSent != SOCKET_ERROR)
        Socket.nSentPosition += numSent;
    else
    {
        INT32 err = WSAGetLastError();
        if (err != WSAWOULDBLOCK)
        {
            CheckIdle(clientId);
            Socket.Error++;
            if (Socket.Error < 10)
                Log(clientId, LOG_INGAME, "Erro no envio do pacote. Total a ser enviado: %d. Error: %d", Socket.nSendPosition, err);
            return FALSE;
        }
    }

    if (Socket.nSentPosition >= Socket.nSendPosition)
    {
        Socket.nSendPosition = 0;
        Socket.nSentPosition = 0;
    }

    return TRUE;
}