0
votes

Good afternoon, recently discovered a problem in doing, is generating error 10035, generating several and several times the error causing the connection of the client is no longer remote and there is a lag without emulator. similarity with the error and I can not find a solution to it, if anyone can give me a light on how I can solve this error I thank. the code is as follows:

xxxx: An error occurred while sending the package. Total to be sent: 500. Error: 10035 xxxx: Error in sending the package. Total to be sent: 568. Error: 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;
}

I do not know if it is possible to undo the following error or something of the type, because when it occurs it generates a disconnection of the user almost instantly, but it stays connected.

1
Very basic mishap, google "winsock error 10035" and read this. - Hans Passant
Error 10035 is WSAWOULDBLOCK, which is NOT a fatal error, but you are treating it as if it were. You are obviously using a non-blocking socket, or you wouldn't be getting that error. So you need to handle the case where send() would block (because the receiver doesn't have enough buffer space to receive more data). Simply retry the same send() operation again, preferably preceeding it with a call to select() to wait (with an optional timeout) for the receiver to free up buffer space before you send data again. - Remy Lebeau

1 Answers

0
votes

Error 10035 is WSAWOULDBLOCK, which is NOT a fatal error, but you are treating it as if it were.

You are obviously using a non-blocking socket, or you wouldn't be getting this "error" in the first place. As such, you need to handle the possibility that send() may fail to block the calling thread (because the receiver doesn't have enough buffer space to receive more data).

Simply retry the same send() operation again, preferably preceeding it with a call to select() to wait (with an optional timeout) for the receiver to free up some buffer space before you send data again.

Try something more like this:

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;
}

Or, if you want the function to exit when a blockage occurs, and not wait for the data to fully send, but to finish sending at a later time:

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;
}