我正在尝试通过TCP / IP协议连接到Delphi中没有的程序,而且我没有关于如何执行此操作的文档。
使用Delphi中的服务,我监视程序的两个客户端之间的通信,并将sendt文本写入文件,所以我可以在我的Delphi程序中播放它。
我设法发送了几件事,但问题是当我必须提供这个文本时:
SOH NUL ÜÜ NUL ENQ NUL Data ENQ NUL NUL NUL SOH NUL NUL NUL NUL 557
我发现字符串部分中有特殊字符,并且无法发送这些数据。
我尝试将其作为字符串发送并输入ASCII值,但特殊字符不起作用。
以下是我的代码的一部分:
TCPClient := TIdTCPClient.Create(nil);
TCPClient.Host := edtIP.Text;
Memo1.Lines.Clear;
TCPClient.Port := PORT;
TCPClient.ConnectTimeout := 20000;
TCPCliente.Connect;
Memo1.Lines.Add('Conectado con el Sevidor');
TCPClient.Socket.ReadTimeout := 20000;
edtTextoEnvio.Text := edtVersion.Text+' '+edtIP.Text+' '+
edtAlias.Text+' '+edtFuncion.Text+' 'edtPassword.Text;
TCPClient.Socket.WriteLnRFC(edtTextoEnvio.Text, IndyTextEncoding_8Bit);
Memo1.Lines.Add('Mensaje Enviado: '+edtTextoEnvio.Text);
TextoRecibido := TCPCliente.Socket.ReadLn(IndyTextEncoding_8Bit);
Memo1.Lines.Add('Mensaje Recibido: '+TextoRecibido);
TCPCliente.Socket.WriteLnRFC(NUNProc, IndyTextEncoding_8Bit);
Memo1.Lines.Add('Mensaje Enviado: '+NUNProc);
envioMensaje:= Char(1)+ Char(0)+'ÜÜ'+ Char(0)+ Char(5)+Char(0)+'Data'+Char()5)+Char(0)+Char(0)+Char(0)+Char(1)+CHar(0)+Char(0)+Char(0)+Char(0)+'557';
TCPCliente.Socket.WriteLnRFC(envioMensaje, IndyTextEncoding_8Bit); //here is the problem
TextoRecibido := TCPCliente.Socket.ReadLn(IndyTextEncoding_8Bit);
Memo1.Lines.Add('Mensaje Recibido: '+TextoRecibido);
答案 0 :(得分:3)
您要发送的某些字符串值中包含非ASCII字符,但套接字没有文本概念,只有字节。您必须使用适当的字符集将字符串编码为字节,然后您可以根据需要发送字节。 Indy具有内置功能,可以为您处理(例如TIdIOHandler.DefStringEncoding
属性,以及基于字符串的AByteEncoding
和TIdIOHandler.Write...()
方法的TIdIOHandler.Read...()
参数。您正在尝试考虑这一点,但您使用错误的Indy编码来执行此操作。 IndyTextEncoding_8bit
并不是真正的字符集,它主要用于处理基于文本的协议中的8位二进制数据,而不应用于通用代码。您需要做的是确定另一方期望您使用的实际字符集。不同的字符集以不同的方式编码相同的非ASCII字符(如果有的话),因此您和另一方必须就相同的字符集达成一致,以对字符串进行编码和解码,否则您将丢失数据。
话虽如此,Indy有不同的方式来完成你的尝试。鉴于您已经显示的数据(如果您显示监控服务实际捕获的数据会更好,或者更好地从Wireshark这样的数据包嗅探器中获取),至少我会建议更类似于以下内容:
TCPClient := TIdTCPClient.Create(nil);
TCPClient.Host := edtIP.Text;
TCPClient.Port := PORT;
TCPClient.ConnectTimeout := 20000;
TCPClient.ReadTimeout := 20000;
Memo1.Lines.Clear;
TCPClient.Connect;
TCPClient.IOHandler.DefStringEncoding := CharsetToEncoding('ISO-8859-1'); // <-- this is just a guess!
Memo1.Lines.Add('Conectado con el Sevidor');
edtTextoEnvio.Text := edtVersion.Text + ' ' + edtIP.Text + ' ' + edtAlias.Text + ' ' + edtFuncion.Text + ' ' + edtPassword.Text;
TCPClient.IOHandler.WriteLn(edtTextoEnvio.Text);
Memo1.Lines.Add('Mensaje Enviado: ' + edtTextoEnvio.Text);
TextoRecibido := TCPClient.IOHandler.ReadLn;
Memo1.Lines.Add('Mensaje Recibido: ' + TextoRecibido);
TCPClient.IOHandler.WriteLn(NUNProc);
Memo1.Lines.Add('Mensaje Enviado: ' + NUNProc);
TCPClient.IOHandler.WriteBufferOpen;
try
TCPClient.IOHandler.Write(Byte(1));
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write('ÜÜ');
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write(Byte(5));
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write('Data');
TCPClient.IOHandler.Write(Byte(5));
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write(Byte(1));
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write('557');
TCPClient.IOHandler.WriteLn;
TCPClient.IOHandler.WriteBufferClose;
except
TCPClient.IOHandler.WriteBufferCancel;
raise;
end;
TextoRecibido := TCPClient.IOHandler.ReadLn;
Memo1.Lines.Add('Mensaje Recibido: ' + TextoRecibido);
话虽这么说,所有这些nul字节更可能是多字节二进制整数的一部分,你可以使用TIdIOHandler.Write(Int16)
,TIdIOHandler.Write(Int32)
等发送:
TCPClient.IOHandler.WriteBufferOpen;
try
{
TCPClient.IOHandler.Write(Byte(1));
TCPClient.IOHandler.Write(Byte(0));
}
TCPClient.IOHandler.Write(Int16(1), False);
TCPClient.IOHandler.Write('ÜÜ');
TCPClient.IOHandler.Write(Byte(0));
{
TCPClient.IOHandler.Write(Byte(5));
TCPClient.IOHandler.Write(Byte(0));
}
TCPClient.IOHandler.Write(Int16(5), False);
TCPClient.IOHandler.Write('Data');
{
TCPClient.IOHandler.Write(Byte(5));
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write(Byte(0));
}
TCPClient.IOHandler.Write(Int32(5), False);
{
TCPClient.IOHandler.Write(Byte(1));
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write(Byte(0));
}
TCPClient.IOHandler.Write(Int32(1), False);
TCPClient.IOHandler.Write(Byte(0));
TCPClient.IOHandler.Write('557');
TCPClient.IOHandler.WriteLn;
TCPClient.IOHandler.WriteBufferClose;
except
TCPClient.IOHandler.WriteBufferCancel;
raise;
end;
ÜÜ
也非常可疑。它很可能实际上不是ÜÜ
字符串,更可能只是字节$DC $DC
,2个8位220
值,16位56540
值等。< / p>
如果没有关于实际通信协议的明确文档,您只是在猜测,有时您可能会猜错。所以我强烈建议您联系其他客户端应用程序的作者并索取文档。或者在线搜索并查看第三方是否已经为该应用编写了此类文档。否则你只是盲目编码,这不是一个好的选择。