У меня есть две симуляции на двух компьютерах, которые генерируют данные.
Чтобы соединить эти две симуляции, у меня есть работающий блок (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;
}