Независимо от того, сколько измерений использует ваш массив, он по-прежнему имеет фиксированный размер в байтах (sizeof(int) * 3 * 3 = 36
), поэтому вы можете использовать методы TIdTCPConnection::WriteBuffer()
и TIdTCPConnection::ReadBuffer()
для его отправки / получения, например:
IdTCPClient1->WriteBuffer(&example, sizeof(example));
AThread->Connection->ReadBuffer(&example, sizeof(example));
Но, если вы не хотите на это полагаться, вы можете отправлять / получать значения int
по отдельности, используя методы TIdTCPConnection::WriteInteger()
и TIdTCPConnection::ReadInteger()
, например:
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
IdTCPClient1->WriteInteger(example[i][j]);
}
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
example[i][j] = AThread->Connection->ReadInteger();
}
Если вместо этого вы используете динамически распределенный массив, вы можете затем отправить отдельные измерения перед отправкой действительных целых чисел, чтобы получатель знал, сколько целых чисел ожидать, чтобы он мог выделить подходящий массив для их получения, например:
IdTCPClient1->WriteInteger(3);
IdTCPClient1->WriteInteger(3);
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
IdTCPClient1->WriteInteger(example[i][j]);
}
rows = AThread->Connection->ReadInteger();
cols = AThread->Connection->ReadInteger();
example = new int*[rows];
for (int i = 0; i < rows; ++i)
{
example[i] = new int[cols];
for (int j = 0; j < cols; ++j)
example[i][j] = AThread->Connection->ReadInteger();
}
При этом, есть несколько проблем с кодом, который вы показали.
Ваш клиент и сервер не совпадают:
Ваш клиент отправляет AnsiString с префиксом длины, за которым следует (не с префиксом счетчика) TStringList. Затем он читает AnsiString с префиксом длины.
Ваш сервер правильно читает AnsiString с префиксом длины клиента, но игнорирует TStringList клиента. Затем он отправляет длину AnsiString, но не отправляет сам AnsiString, за которым следует (не с префиксом) TStringList. Клиент не будет правильно читать TStringList.
Ваш обработчик TIdTCPServer :: OnExecute не синхронизируется с основным потоком пользовательского интерфейса при доступе к элементам управления пользовательского интерфейса. TIdTCPServer - это многопоточный компонент, его события запускаются в контексте рабочих потоков, а не основного потока пользовательского интерфейса. Вы ДОЛЖНЫ синхронизироваться при доступе к пользовательскому интерфейсу из рабочего потока, иначе произойдет что-то плохое.
Попробуйте вместо этого:
Клиент:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
String s = Edit1->Text;
int example[3][3];
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
example[i][j] = (i*3)+j;
}
IdTCPClient1->Connect();
try
{
//send byte length
IdTCPClient1->WriteInteger(s.Length());
//send text
IdTCPClient1->Write(s);
// send array
IdTCPClient1->WriteBuffer(&example, sizeof(example));
ListBox1->Items->Add(s + ">>sent");
int bytes = IdTCPClient1->ReadInteger();
String resp = IdTCPClient1->ReadString(bytes);
ListBox1->Items->Add(resp);
}
__finally
{
IdTCPClient1->Disconnect();
}
}
//---------------------------------------------------------------------------
Сервер:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include <IdSync.hpp>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
class TAddToListBoxSync : public TIdSync
{
public:
String str;
__fastcall TAddToListBoxSync(const String &s) : TIdSync(), str(s) {}
virtual void __fastcall DoSynchronize() { Form1->ListBox1->Items->Add(str); }
};
class TSetEditTextSync : public TIdSync
{
public:
String str;
__fastcall TSetEditTextSync(const String &s) : TIdSync(), str(s) {}
virtual void __fastcall DoSynchronize() { Form1->Edit1->Text = str; }
};
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdTCPServer1Execute(TIdPeerThread *AThread)
{
int bytes = AThread->Connection->ReadInteger();
String request = AThread->Connection->ReadString(bytes);
int example[3][3];
AThread->Connection->ReadBuffer(&example, sizeof(example));
TAddToListBoxSync *lb_sync = new TAddToListBoxSync(request);
try {
lb_sync->Synchronize();
}
__finally {
delete lb_sync;
}
String risp = FormatDateTime("hh:mm AM/PM", Now());
TSetEditTextSync *edt_sync = new TSetEditTextSync(risp);
try {
edt_sync->Synchronize();
}
__finally {
delete edt_sync;
}
AThread->Connection->WriteInteger(risp.Length());
AThread->Connection->Write(risp);
lb_sync = new TAddToListBoxSync(risp + ">> inviato");
try {
lb_sync->Synchronize();
}
__finally {
delete lb_sync;
}
AThread->Connection->Disconnect();
}
//---------------------------------------------------------------------------