C++Builder使用TCP发送数组
在C++Builder中,我必须发送一个多维int数组,如: 使用TCP协议 我使用以下视频创建了一个套接字: 但我不明白如何只发送多维数组而不是字符串。。。有什么提示吗 客户端代码:C++Builder使用TCP发送数组,c++,tcp,c++builder,C++,Tcp,C++builder,在C++Builder中,我必须发送一个多维int数组,如: 使用TCP协议 我使用以下视频创建了一个套接字: 但我不明白如何只发送多维数组而不是字符串。。。有什么提示吗 客户端代码: //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" //-----------------
//---------------------------------------------------------------------------
#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)
{
IdTCPClient1->Connect();
//send byte
IdTCPClient1->WriteInteger(Edit1->Text.Length());
//send text
IdTCPClient1->Write(Edit1->Text);
//send request
TStringList *SL = new TStringList;
SL->Add(Edit1->Text);
IdTCPClient1 ->WriteStrings(SL);
delete SL;
ListBox1->Items->Add(Edit1->Text+">>sent");
int bytes = IdTCPClient1 -> ReadInteger();
AnsiString resp = IdTCPClient1->ReadString(bytes);
ListBox1->Items->Add(resp);
IdTCPClient1->Disconnect();
}
//---------------------------------------------------------------------------
服务器代码:
//---------------------------------------------------------------------------
#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::IdTCPServer1Execute(TIdPeerThread *AThread)
{
int bytes = AThread->Connection->ReadInteger();
AnsiString request = AThread->Connection->ReadString(bytes);
ListBox1->Items->Add(request);
Edit1->Text=FormatDateTime("hh:mm AM/PM", Now());
AnsiString risp = Edit1->Text;
AThread->Connection->WriteInteger(risp.Length());
TStringList *SL = new TStringList;
SL->Add(risp);
AThread->Connection->WriteStrings(SL);
delete SL;
ListBox1->Items->Add(risp+">> inviato");
AThread->Connection->Disconnect();
}
//---------------------------------------------------------------------------
无论数组使用多少个维度,它仍然有一个固定的字节大小sizeofint*3*3=36,因此可以使用TIdTCPConnection::WriteBuffer和TIdTCPConnection::ReadBuffer方法发送/接收它,例如:
IdTCPClient1->WriteBuffer(&example, sizeof(example));
但是,如果您不想依赖于此,则可以使用TIdTCPConnection::WriteInteger和TIdTCPConnection::ReadInteger方法分别发送/接收int值,例如:
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
IdTCPClient1->WriteInteger(example[i][j]);
}
如果改为使用动态分配的数组,则可以在发送实际整数之前发送各个维度,这样接收器就会知道预期的整数数量,从而可以分配合适的数组来接收它们,例如:
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]);
}
也就是说,您所展示的代码有几个问题
您的客户端和服务器不匹配:
您的客户机正在发送一个长度前缀为AnsiString,后跟一个not count前缀为TStringList。然后,它读取一个长度前缀AnsiString
您的服务器正在正确读取以AnsiString为前缀的客户端长度,但忽略了客户端的TStringList。然后,它发送一个AnsiString的长度,但不发送AnsiString本身,后跟前缀为TStringList的not count。客户端将无法正确读取TStringList
访问UI控件时,您的TIdTCPServer::OnExecute处理程序未与主UI线程同步。TIdTCPServer是一个多线程组件,它的事件在工作线程的上下文中触发,而不是在主UI线程中。从工作线程访问UI时必须同步,否则会发生错误
请尝试以下方法:
客户:
//---------------------------------------------------------------------------
#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();
}
//---------------------------------------------------------------------------
您尚未显示所有代码。什么是IdTCPClient1?请参阅并考虑创建一个以改进您的问题。它只是C++ Builder的一个组件,如果您从Indy客户端选择TCP客户端,IDTCPclient 1是标准名称:明白了,但是省略这一点,对于那些没有C++ Builder的人来说,很难或不可能,并且没有很多额外的时间来观看YouTube视频,比如我自己来帮助你诊断问题。@蓝发FFY,你的代码是使用了9年,这已经超过十年了。考虑升级到印地10。
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();
}
//---------------------------------------------------------------------------
#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();
}
//---------------------------------------------------------------------------