C ++ - Слишком медленное моделирование с использованием TCP / IP - PullRequest
0 голосов
/ 01 июля 2019

У меня есть две симуляции на двух компьютерах, которые генерируют данные. Чтобы соединить эти две симуляции, у меня есть работающий блок (IPTunnel), который передает данные из одной симуляции в другую (на другом компьютере), чтобы она продолжала работать. Проблема заключается в оптимизации TCP-соединения.

Две симуляции на одном компьютере занимают около 3 минут, но когда на двух компьютерах, это занимает около 1 часа.

Что я могу сделать, чтобы улучшить скорость TCP-соединения?

Заранее спасибо!

Это код для отправки данных:

void IPTunnel::ipTunnelSendInt(int space) {
    int data = space;
    char* tosend = (char*)& data;
    int remaining = sizeof(data);
    int result = 0;
    int sent = 0;
    while (remaining > 0) {
        result = send(clientSocket, tosend + sent, remaining, 0);
        if (result > 0) {
            remaining -= result;
            sent += remaining;
        }
        else if (result < 0) {
            //printf("ERROR sending int!\n");
            // probably a good idea to close socket
            break;
        }
    }
}

int IPTunnel::ipTunnelRecvInt() {
    int value = 0;
    char* recv_buffer = (char*)& value;
    int remaining = sizeof(int);
    int received = 0;
    int result = 0;
    while (remaining > 0) {
        result = recv(clientSocket, recv_buffer + received, remaining, 0);
        if (result > 0) {
            remaining -= result;
            received += result;
        }
        else if (result == 0) {
            printf("Remote side closed his end of the connection\n");
            // probably a good idea to close socket
            break;
        }
        else if (result < 0) {
            //printf("ERROR receiving int!\n");
            // probably a good idea to close socket
            break;
        }
    }
    return value;
}

(....)

case signal_value_type::t_message:
        for (int k = 0; k < process; k++) {
            t_message message;
            inputSignals[0]->bufferGet(&message);

            t_message_type valueMType = MessageProcessors::getMessageType(message);
            t_message_data_length valueMDataLength = MessageProcessors::getMessageDataLength(message);

            ipTunnelPut(valueMType);
            ipTunnelSendInt(valueMDataLength);
            //////////////////////////////////////////////
            // Point of sending msg length

            string data = message.messageData;

            ipTunnelSendInt((int)data.size());
            int numberOfMessages = (int)ceil(data.size() / 511.0);
            string tmpMsg;
            int msgSent = 0;
            int msgToSend = (int)min(data.size(), 511);

            for (int it = 0; it < numberOfMessages; ++it) {
                char msg[512];


                tmpMsg.assign(data.begin() + msgSent, data.begin() + msgSent + msgToSend);
                msgSent = msgSent + msgToSend;
                msgToSend = (int)min(data.size() - msgSent, 511);
                //acrescentar if se o size for maior que msg
//              if (valueMDataLength > 512)
//                  printf("TAMANHO É MAIOR QUE 512");
                strncpy_s(msg, tmpMsg.c_str(), sizeof(msg));

                //                  msg[sizeof(msg) - 1] = 0;

                int strSz = (int)strlen(msg);


                char* tosend = (char*)& msg;
                int remaining = strSz;
                int result = 0;
                int sent = 0;
                while (remaining > 0) {
                    result = send(clientSocket, tosend + sent, remaining, 0);
                    if (result > 0) {
                        remaining -= result;
                        sent += remaining;
                    }
                    else if (result < 0) {
                        printf("ERROR!\n");
                        // probably a good idea to close socket
                        break;
                    }
                }
            }
        }
        break;

Это общий код блока:

#include "../include/ip_tunnel_ms_windows_20180815.h" 
#include "../include/message_processor_common_20190410.h"


SOCKET clientSocket;
int n = 0;
void IPTunnel::initialize(void)
{

    if (inputSignals.empty()) {
        printf("server%d\n", n++);
        if (!server()) {
            printf("Error opening server\n");
            ::exit(1);
        }
    }
    else {
        printf("client%d\n", n++);
        if (!client()) {
            printf("Error opening client\n");
            ::exit(1);
        }
    }
}


bool IPTunnel::runBlock(void)
{
    .....
    (transmit data)
    .....
    return true;
}

void IPTunnel::terminate(void) {
    closesocket(clientSocket);
    WSACleanup();
}

bool IPTunnel::server() {
    WSADATA wsData;
    WORD ver = MAKEWORD(2, 2);

    int wsOk = WSAStartup(ver, &wsData);
    if (wsOk != 0)
    {
        cerr << "Can't Initialize winsock! Quitting" << endl;
        return false;
    }

    SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
    if (listening == INVALID_SOCKET)
    {
        cerr << "Can't create a socket! Quitting" << endl;
        return false;
    }

    sockaddr_in hint;
    hint.sin_family = AF_INET;
    hint.sin_port = ntohs(tcpPort);
    //inet_pton(AF_INET, (PCSTR)remoteMachineIpAddress.c_str(), &hint.sin_addr.s_addr); // hint.sin_addr.S_un.S_addr = inet_addr(ipAddressServer.c_str());
    hint.sin_addr.S_un.S_addr = INADDR_ANY;


    if (::bind(listening, (sockaddr*)& hint, sizeof(hint)) < 0) {
        printf("\n ERROR on binding");
        return false;
    }

    if (listen(listening, SOMAXCONN) == -1) {
        printf("\n ERROR on binding");
        return false;
    }

    sockaddr_in client;
    int clientSize = sizeof(client);

    clientSocket = accept(listening, (sockaddr*)& client, &clientSize);

    char host[NI_MAXHOST];
    char service[NI_MAXSERV];

    ZeroMemory(host, NI_MAXHOST);
    ZeroMemory(service, NI_MAXSERV);

    if (getnameinfo((sockaddr*)& client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
    {
        cout << host << " connected on port " << service << endl;
    }
    else
    {
        inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
        cout << host << " connected on port " <<
            ntohs(client.sin_port) << endl;
    }
    return true;
}

bool IPTunnel::client() {

    WSAData data;
    WORD ver = MAKEWORD(2, 2);
    int wsResult = WSAStartup(ver, &data);
    if (wsResult != 0)
    {
        cerr << "Can't start Winsock, Err #" << wsResult << endl;
        return false;
    }

    clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket == INVALID_SOCKET)
    {
        cerr << "Can't create socket, Err #" << WSAGetLastError() << endl;
        WSACleanup();
        return false;
    }

    sockaddr_in hint;
    hint.sin_family = AF_INET;
    hint.sin_port = htons(tcpPort);
    inet_pton(AF_INET, remoteMachineIpAddress.c_str(), &hint.sin_addr);

    int connResult = -2;
    while (connResult != 0 || numberOfTrials == 0) {
        connResult = connect(clientSocket, (sockaddr*)& hint, sizeof(hint));
        if (connResult == SOCKET_ERROR)
        {
            cerr << "Can't connect to server, Err #" << WSAGetLastError() << endl;
            cerr << "Waiting " << timeIntervalSeconds << " seconds." << endl;
        }

        Sleep(timeIntervalSeconds * 1000);
        ;
        if (--numberOfTrials == 0) {
            cerr << "Reached maximum number of attempts." << endl;
            ::exit(1);
        }
    }
    cout << "Connected!\n";
    return true;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...