连接3个以上客户端时,TCP / IP通信速度变慢

时间:2018-06-09 12:34:56

标签: c networking tcp network-programming directx

我使用direct-X制作简单的TCP / IP多客户游戏 仅连接两个客户端时,服务器和客户端通信良好 当超过三个时,每个客户端收到的数据慢于两个 服务器和客户端在收到数据时创建线程, 我认为服务器的回送发送速度无法赶上recv速度 那么,我如何使服务器更快地发送数据包? 这是我的代码

DWORD WINAPI NetReceive(LPVOID socketConnect)
{
    char recvBuffer[127];
    int  RecvBytes;

    Packet  recvPacket;
    char    receiveBuffer[PACKETBUFFERSIZE];
    int     receivedPacketSize = 0;


    while (1) {

        ///////////////////////////////////////////////////////
        // replace codes below into accurately reveiced routine using "Packet"
        int bufSize;

        bufSize = PACKETBUFFERSIZE - receivedPacketSize;

        RecvBytes = ::recv((SOCKET)socketConnect, &receiveBuffer[receivedPacketSize], bufSize, 0);

        receivedPacketSize += RecvBytes;

        while (receivedPacketSize > 0)  // parsing Packet Length
        {
            recvPacket.copyToBuffer(receiveBuffer, receivedPacketSize);
            int packetlength = (int)recvPacket.getPacketSize();

            if (receivedPacketSize >= packetlength)
            {
                //  Parsing, main routine 
                recvPacket.readData(recvBuffer, recvPacket.getDataFieldSize());
                printf("(%d Bytes, ID=%d) %s\n", recvPacket.getDataFieldSize(), recvPacket.id(), recvBuffer);

                //::send( socketClient[k], recvBuffer, strlen(recvBuffer)+1, 0 );

                receivedPacketSize -= packetlength;
                if (receivedPacketSize > 0)
                {
                    ::CopyMemory(recvBuffer, (receiveBuffer + recvPacket.getPacketSize()), receivedPacketSize);
                    ::CopyMemory(receiveBuffer, recvBuffer, receivedPacketSize);
                }
            }
            else
                break;
        }

        if (RecvBytes<1)
            break;
        printf("%d> %d : %s\n", socketConnect, RecvBytes, recvBuffer);

        if (recvBuffer[RecvBytes - 2] == '.')
            break;


        ///////////////////////////////////////////////////////

    }

    return NULL;
}

void main(int argc, char **argv)
{
    WSADATA wsaData;
    SOCKET socketConnect[MAX_CLIENT];
    struct sockaddr_in serverAddr;
    int  k;
    HANDLE handleThread[MAX_CLIENT];


    ::WSAStartup(0x202, &wsaData);


    for (k = 0;k<MAX_CLIENT;k++) {
        socketConnect[k] = INVALID_SOCKET;
        socketConnect[k] = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (socketConnect[k] == INVALID_SOCKET)
        {
            printf("Cannot create socket %d !!\n", k);
            continue;
        }
    }



    //******************************* Address and port resolve
    char serverName[120], serverPort[120];

    if (resolveAddr(argc, argv, serverName, serverPort)<1) {
        printf("*** Unable to resolve server name !\n");
        ExitProcess(-1);
    }

    //  접속할 서버의 정보를 설정한다.
    ::memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = ::inet_addr(serverName);
    serverAddr.sin_port = ::htons(atoi(serverPort));

    //********************************************************

    for (k = 0;k<MAX_CLIENT;k++) {
        if (socketConnect[k] != INVALID_SOCKET) {
            if (::connect(socketConnect[k], (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
            {
                printf("Cannot connect to server %d !!\n", k);
                socketConnect[k] = INVALID_SOCKET;
                continue;
            }
            else {
                // create thread for receive
                handleThread[k] = CreateThread(NULL, 0, NetReceive, (void *)socketConnect[k], THREAD_PRIORITY_NORMAL, NULL);
            }
        }
    }

    Packet sendPacket;

    //  서버와 통신을 한다.
    int count = 0;
    while (count++ < MAX_MESSAGE) {
        char sendBuffer[127];
        int sentBytes;

        for (k = 0;k<MAX_CLIENT;k++) {

            if (socketConnect[k] != INVALID_SOCKET) {
                char Input[127];
                scanf("%127s", Input);
                sprintf(sendBuffer, "%d>%s", k,Input);
                if (count == MAX_MESSAGE)
                    strcat(sendBuffer, ".");

                ///////////////////////////////////////////////////////////

                sendPacket.clear();
                sendPacket.id(1000 + count);
                sendPacket.writeData(sendBuffer, strlen(sendBuffer) + 1);

                sentBytes = ::send(socketConnect[k], sendPacket.getPacketBuffer(), sendPacket.getPacketSize(), 0);
                //              printf(">> send %d %d %s \n", sendPacket.id(), sendPacket.getPacketSize(), sendPacket.getPacketBuffer()+4 );

                //              sentBytes = ::send( socketConnect[k], sendBuffer, ::strlen( sendBuffer ) + 1, 0 );

                ///////////////////////////////////////////////////////////

                if (sentBytes<0) {
                    ::shutdown(socketConnect[k], SD_BOTH);
                    ::closesocket(socketConnect[k]);
                    socketConnect[k] = INVALID_SOCKET;
                }
            }
        }

        //      Sleep(200);
    }


    ::WaitForMultipleObjects(MAX_CLIENT, handleThread, TRUE, INFINITE);


    for (k = 0;k<MAX_CLIENT;k++) {
        ::shutdown(socketConnect[k], SD_BOTH);
        ::closesocket(socketConnect[k]);
    }
    ::WSACleanup();

    printf("Server Connection Closed !\n");
    char temp[120];
    fgets(temp, 119, stdin);
}

0 个答案:

没有答案