⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sockets.cpp

📁 WYD Server 753 (Development)
💻 CPP
字号:
#include "sockets.h"
#include "encdec.h"#include "client.h"#include "server.h"
cSocket::cSocket()
{
    FD_ZERO(&fdSocket);

    timeout.tv_sec = 0;
	timeout.tv_usec = 0;

    dbSocket = INVALID_SOCKET;
    srvSocket = INVALID_SOCKET;

    socketCount = 0;
    memset(LSocket, INVALID_SOCKET, sizeof(LSocket));
}

cSocket::~cSocket()
{
    sSocket *ptrSocket = LSocket;
    for(u32 var = 0; var < socketCount; ptrSocket++)
    {
        if(ptrSocket->Sock != INVALID_SOCKET)
        {
            closesocket(ptrSocket->Sock);
            ptrSocket->Sock = INVALID_SOCKET;

            var++;
        }
    }

    socketCount = 0;
    FD_ZERO(&fdSocket);
}
// Le o arquivo de configuracao do socket//// Retorna false se o arquivo nao foi encontrado// Retorna true se o arquivo foi lido com sucesso
bool cSocket::ReadConfig()
{    const char *def = "socket.ini";
    FILE *fp = fopen(def, "r");
    if(fp == NULL)
    { /* not found */
        Log(WARN, Server.GetMessage(FILENOTFOUND), def);
        return false;
    }

    char cmd[16], val[16];
    while(fgets(bufRecv, sizeof(bufRecv), fp))
    {
        if(bufRecv[0] == '#' || bufRecv[0] == '\n')
            continue;

        sscanf(bufRecv, "%s = %s", cmd, val);

        if(strcmp(cmd, "srvIP") == 0)
            strcpy(srvIP, val);
        else if(strcmp(cmd, "srvPort") == 0)
            srvPort = atoi(val);
        else if(strcmp(cmd, "dbIP") == 0)
            strcpy(dbIP, val);
        else if(strcmp(cmd, "dbPort") == 0)
            dbPort = atoi(val);
    }

    fclose(fp);
    Log(NORMAL, Server.GetMessage(FILELOADED), def);
    return true;
}

// Inicia a conexao do socket do server
//
// Retorna false se ocorreu um erro durante a cricao do socket
// Retorna true se o socket foi iniciado com sucesso
bool cSocket::StartServer()
{
    srvSocket = socket(AF_INET, SOCK_STREAM, 0);
    if(srvSocket == INVALID_SOCKET)
    { // Erro ao criar o socket
        Log(WARN, "socket() failed in cSocket::StartServer()");
    }
    else
    { // Executa o bind
        sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = inet_addr(srvIP);
        addr.sin_port = htons(srvPort);
        memset(addr.sin_zero, 0, sizeof(addr.sin_zero));

        if(bind(srvSocket, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
        { // Erro ao executar a funcao bind
            Log(WARN, "bind() failed in cSocket::StartServer()");
        }
        else
        { // Executa o listen e adiciona o socket
            if(listen(srvSocket, 8) == SOCKET_ERROR)
            { // Erro ao executar a funcao listen
                Log(WARN, "listen() failed in cSocket::StartServer()");
            }
            else
            { // Adiciona o socket do servidor na lista dos sockets
                sSocket sSock;
                sSock.clientID = 0;
                sSock.lastPacket = 0;
                sSock.Sock = srvSocket;
                sSock.socketInfo = addr;

                AddSocket(sSock, 0);
                return true;
            }
        }
    }

    return false;
}

// Inicia a conexao do socket da database
//
// Retorna false se ocorreu um erro durante a cricao do socket
// Retorna true se o socket foi iniciado com sucesso
bool cSocket::StartDatabase()
{
    dbSocket = socket(AF_INET, SOCK_STREAM, 0);
    if(dbSocket == INVALID_SOCKET)
    { // Erro ao criar o socket
        Log(WARN, "socket() failed in cSocket::StartDatabase()");
    }
    else
    { // Conecta na database
        sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = inet_addr(dbIP);
        addr.sin_port = htons(dbPort);
        memset(addr.sin_zero, 0, sizeof(addr.sin_zero));

        if(connect(dbSocket, (sockaddr*)&addr, sizeof(sockaddr_in)) == SOCKET_ERROR)
        { // Database nao foi encontrada
            Log(WARN, "connect() failed in cSocket::StartDatabase()");
        }
        else
        { // Envia os pacotes de login            u32 helloPacket = 0x1F11F311;            if(send(dbSocket, (char*)&helloPacket, 4, 0) != 4)            { // Erro ao enviar o pacote de hello                Log(WARN, Server.GetMessage(ERRORSEND));            }            else            { // Envia o pacote de login                sSocket sSock;                sSock.clientID = DATABASE_ID;                sSock.lastPacket = time(NULL);                sSock.Sock = dbSocket;                sSock.socketInfo = addr;                // Header                pDB_1h *pServer = (pDB_1h*)bufRecv;                pServer->Header.packetSize = sizeof(pDB_1h);                pServer->Header.opCode = 0x001;                pServer->Header.clientID = 0;                pServer->isGameServer = 1;                if(!cClient::Send(sSock, bufRecv, sizeof(pDB_1h)))                { // Erro ao enviar o pacote de login                    Log(WARN, Server.GetMessage(ERRORSEND));                }                else                { // Adiciona o socket da database na lista dos sockets
                    AddSocket(sSock, 1);
                    return true;                }            }            // Fecha a conexao da database            closesocket(dbSocket);            dbSocket = INVALID_SOCKET;
        }
    }

    return false;
}

// Verifica se o socket esta inativo
void cSocket::CheckSockets()
{
    sSocket *ptrSock = &LSocket[2];
    for(u32 x = 2; x < socketCount; ptrSock++)
    { // Procura os socket validos
        if(ptrSock->Sock != INVALID_SOCKET)
        { // Socket valido
            int timenow = time(NULL);

            if(ptrSock->clientID == INVALID_ID)
            { // Client ainda nao se logou
                if((ptrSock->lastPacket + 5) < timenow)
                { // Tempo maximo de espera pelo pacote de login
                    DeleteSocket(*ptrSock);
                    continue;
                }
            }            else if((ptrSock->lastPacket + 305) < timenow)            { // Client nao enviou nenhum pacote                Log(INFO, Server.GetMessage(CLOSINGCLIENTTIME), ptrSock->clientID);                // Deleta o client da lista                DeleteSocket(*ptrSock);                continue;            }

            x++;
        }
    }    ptrSock = &LSocket[1];    if((ptrSock->lastPacket + 55) < time(NULL))    { // Envia o pacote de ping para nao ser desconectado        pDB_2h *pServer = (pDB_2h*)bufRecv;        pServer->Header.packetSize = sizeof(pDB_2h);        pServer->Header.opCode = 0x002;        pServer->Header.clientID = 0;        if(!cClient::Send(*ptrSock, bufRecv, sizeof(pDB_2h)))        { // Erro ao enviar o pacote de ping            Log(WARN, Server.GetMessage(PINGERROR));            GameServer->CloseApp();            return ;        }        // Atualiza a ultima data do envio de um pacote        ptrSock->lastPacket = time(NULL);    }
}
// Adiciona o socket//// Retorna false se a lista esta cheia// Retorna true se o socket foi adicionado
bool cSocket::AddSocket(sSocket &sSock, s32 id)
{
    if(id == -1)
    { // Procura uma id que nao esta sendo usada
        for(id = 2; id < FD_SETSIZE; id++)
            if(LSocket[id].Sock == INVALID_SOCKET)
                break;

        if(id == FD_SETSIZE)
            return false;
    }

    if(sSock.Sock >= maxfd)
        maxfd = sSock.Sock + 1;

    socketCount++;
    LSocket[id] = sSock;
    FD_SET(sSock.Sock, &fdSocket);
    return true;
}

// Aceita novos clients no socket do servidor
//
// Retorna false se o socket do servidor 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -