Delphi 如何将多行TStrings数据从TIdTCPServer传递到TIdTCPClient
我试图将数据库记录从服务器端应用程序传递到客户端应用程序。在客户端,我需要将数据存储到Delphi 如何将多行TStrings数据从TIdTCPServer传递到TIdTCPClient,delphi,unicode,delphi-xe3,indy10,tstringlist,Delphi,Unicode,Delphi Xe3,Indy10,Tstringlist,我试图将数据库记录从服务器端应用程序传递到客户端应用程序。在客户端,我需要将数据存储到TStrings集合中 当我传递一个多行字段时,我在客户端收到两个独立的数据项,而不是一个多行数据项!我也尝试使用基于Unicode UTF8的命令来实现这一点,但不幸的是结果是一样的 服务器端代码: procedure TForm1.IdCmdTCPServer1CommandHandlers0Command(ASender: TIdCommand); var myData: TStrings; begi
TStrings
集合中
当我传递一个多行字段时,我在客户端收到两个独立的数据项,而不是一个多行数据项!我也尝试使用基于Unicode UTF8的命令来实现这一点,但不幸的是结果是一样的
服务器端代码:
procedure TForm1.IdCmdTCPServer1CommandHandlers0Command(ASender: TIdCommand);
var
myData: TStrings;
begin
myData := TStringList.Create;
myData.Add('12'); // ID
myData.Add('This is a multi line' + #13#10 + 'description.'); // Descriptions
myData.Add('Thom Smith'); // Name
try
ASender.Context.Connection.Socket.Write(myData, True{, TIdTextEncoding.UTF8});
finally
myData.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
myData: TStrings;
begin
with TIdTCPClient.Create(nil) do
begin
Port := 1717;
Host := 'localhost';
try
Connect;
//IOHandler.DefStringEncoding := TIdTextEncoding.UTF8;
myData := TStringList.Create;
try
SendCmd('greating');
Socket.ReadStrings(myData, -1{, TIdTextEncoding.UTF8});
eID.Text := myData[0]; // ID TEdit
mDes.Text := myData[1]; // Descriptions TMemo
eTelNo.Text := myData[2]; // Name TEdit
finally
myData.Free;
end;
finally
Disconnect;
Free;
end;
end;
end;
myData
服务器端的调试时间值为:
myData[0] = '12'
myData[1] = 'This is a multi line'#$D#$A'description.'
myData[2] = 'Thom Smith'
客户端代码:
procedure TForm1.IdCmdTCPServer1CommandHandlers0Command(ASender: TIdCommand);
var
myData: TStrings;
begin
myData := TStringList.Create;
myData.Add('12'); // ID
myData.Add('This is a multi line' + #13#10 + 'description.'); // Descriptions
myData.Add('Thom Smith'); // Name
try
ASender.Context.Connection.Socket.Write(myData, True{, TIdTextEncoding.UTF8});
finally
myData.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
myData: TStrings;
begin
with TIdTCPClient.Create(nil) do
begin
Port := 1717;
Host := 'localhost';
try
Connect;
//IOHandler.DefStringEncoding := TIdTextEncoding.UTF8;
myData := TStringList.Create;
try
SendCmd('greating');
Socket.ReadStrings(myData, -1{, TIdTextEncoding.UTF8});
eID.Text := myData[0]; // ID TEdit
mDes.Text := myData[1]; // Descriptions TMemo
eTelNo.Text := myData[2]; // Name TEdit
finally
myData.Free;
end;
finally
Disconnect;
Free;
end;
end;
end;
myData
客户端调试时间值:
myData[0]=“12”
myData='这是一个多行'
myData[2]=“说明。”
Telnet结果:
实际上,myData[2]
应该保留的'Thom Smith'
被替换为Description字段的第二行!myData[2]
之后没有项目<代码>我的数据[3]不再可访问
我认为这个问题与Indy的Write
或ReadStrings
过程有关,因为它将ItemCount发送为3,但它发送两个项目(一个正确,下一个是两个项目!)
如何将回车符传递到另一侧,而不使Write
过程中断myData[1]
分成两行
非常感谢。不要使用
t字符串
重载,因为它似乎将换行符用作字符串之间的分隔符,如果字符串本身包含换行符,则该分隔符不起作用
您可以轻松地编写自己的包装器方法,通过线路发送字符串列表(将其视为伪代码):
如果你想
TStrings.Text
忘记特殊字符,你应该在通过网络发送之前转义它们,然后取消转义。逃跑的方法有很多,所以选择一种适合你的方法
function EscapeString:(String): String --- your choice
function DeEscapeString:(String): String --- your choice
procedure SendEscapedStrings(const socket: TIdSocket; const data: TStrings);
var s: string; temp: TStringList;
begin
temp := TStringList.Create;
try
temp.Capacity := data.Count;
for s in data do
temp.Add( EscapeString( s ) );
socket.Write(temp);
finally
temp.Destroy;
end;
end;
procedure ReadDeescapedStrings(const socket: TIdSocket; const data: TStrings);
var s: string; temp: TStringList;
begin
temp := TStringList.Create;
try
Socket.ReadStrings(temp, -1);
data.Clear;
data.Capacity := temp.Count;
for s in temp do
temp.Add( DeEscapeString( s ) );
finally
temp.Destroy;
end;
end;
现在的问题是,对于DeEscapeString
和EscapeString
,您会选择什么?选择很多
- 您可以选择在发送前将字符串转换为base64,在读取后从base64转换字符串
- 您可以选择用于转义的UUENCODE和用于反转义的UUENCODE
- 您可以选择yEnc:
- 或者你可以从
中选择非常简单的函数JclString
和StrStringToEscaped
从绝地代码库()中选择一个单位:strescapedtoestring
什么样的逃跑 如果您要求建议,我建议不要使用原始TCP服务器。有著名的标准HTTP协议,有许多用于Delphi实现HTTP服务器和HTTP客户端的库。在协议(和库)中,已经决定了一些事情,比如加密、压缩、语言支持等。如果出现问题,您可以使用任何HTTP嗅探器,用自己的眼睛查看谁出了问题—clent或服务器。调试要简单得多 如果您刚刚开始,我建议您研究HTTP+JSON Synopse mORMot库,也许它可以满足您的需求。例如,您可以从库中的演示中获取示例服务器代码 然后,若要安排原始TCP服务器,我会发送压缩数据,这样它会工作得更好(网络通常比CPU慢)。看 发送:
- 1:发送到网络(int32)-TStringList.Count
- 2:每做一根弦
- 2.1从字符串[i]创建
TStringStream
- 2.2通过TZCompressionStream传递
- 2.3发送(int32)压缩数据的大小
- 2.4发送数据本身
- 2.5释放临时溪流
- 1:从网络接收(int32)-数据包计数
- 1.1结果晶莹剔透;ResultStringList.Capacity:=读取计数
- 2:每做一根弦
- 2.1创建
tbytestream
- 2.2从网络读取(int32)压缩数据的大小
- 2.3将N个字节从网络读入BytesStream
- 2.4通过TZDecompressionStream将其解包至TStringStream
- 2.5结果字符串.添加(字符串流->字符串)李>
- 2.6释放临时溪流
现在,如果你真的不想改变任何事情,那么JCL转义对你来说就足够了。至少它对我有效,但我的任务非常不同,与网络无关。但是你可以测试它们,看看它是如何工作的。
ReadString()
需要一个字节长度作为输入,但你没有指定一个。@Remy:我没有可用的Delphi…这就是为什么我明确提到这是伪代码。@jpfollenius:我在Stackoverflow中问这个问题之前尝试过这个方法。但问题就在这里,ReadString()
需要发送字符串的长度,而我的发送字符串长度是可变的。@FarshadH。那么在字符串本身之前发送字符串的长度,有什么问题吗?@FarshadH。标准方法是电子邮件/NNTP或HTTP或XMPP(这些标准的一部分是标准编码方法,这是标准方法的唯一定义)。他们多年来一直在努力解决这些问题,并且拥有许多用于测试/调试的工具。甚至只是在服务器上运行压力测试。任何你自己的协议都不是标准的。特别是如果您想为您的服务器开发一个移动客户端,然后使用公共标准确保您拥有世界上所有的工具可供选择,而不是从二进制级别(包括字节顺序)重新实现您自己的协议。谢谢您的建议。我需要发送Unicode字符串。您建议使用哪种类型的转义?@FarshadH-ZStream(),因此它将被压缩。从上面的选项-只要尝试所有的选项,看看会脚你。我最近使用了JCL选项,它非常愚蠢,但很有效,至少在我的例子中是这样。