Delphi Indy TCP通信和线路中断

Delphi Indy TCP通信和线路中断,delphi,encryption,indy,Delphi,Encryption,Indy,我有一个错误,把我搞糊涂了。以下代码将一行代码从TidTCPClient发送到TidTCPServer。第一次执行时,它工作得非常完美。第二次执行时,每次执行之后,它都会在每个字符串的开头添加一个换行符。我错过了什么?(我知道这样做很奇怪,但完整代码中需要客户列表) 我发现您的客户端代码中有一个潜在问题,ClientList.unlocklist应该在循环之外执行: procedure TClientForm.ButtonSendStringClick(Sender: TObject); var

我有一个错误,把我搞糊涂了。以下代码将一行代码从TidTCPClient发送到TidTCPServer。第一次执行时,它工作得非常完美。第二次执行时,每次执行之后,它都会在每个字符串的开头添加一个换行符。我错过了什么?(我知道这样做很奇怪,但完整代码中需要客户列表)


我发现您的客户端代码中有一个潜在问题,
ClientList.unlocklist
应该在循环之外执行:

procedure TClientForm.ButtonSendStringClick(Sender: TObject);
var
  I: integer;
  List      : TList; 
begin     
  List := ClientList.LockList;
  try
   for I := 0 to (List.Count- 1) do
    begin
      ShowMessage('Text to encrypt is ' + Edit1.Text);
      TidTCPClient(List[I]).IOHandler.WriteLn((Encrypt(Edit1.Text,'Pass')+'|x|'));      
    end;
  finally
   ClientList.UnlockList;
  end;
  Edit1.Text := '';
end;
不要在服务器的执行事件中使用showmessage,因为这不是必须使用
同步
或使用其他日志记录方法的主GUI线程。 另一个潜在问题是,加密字符串可能包含回车字符,甚至包含空字符(#0)。在这种情况下,服务器的
Readln
方法将无法读取整个加密字符串,因此无法解密。 解决此问题的一种方法是使用
base64编码

编辑

问题在于您将“|x |”终止符与ReadLn结合使用。因为您是从客户端使用writeln,所以可以这样做

procedure TClientForm.IdTCPServer1Execute(AContext: TIdContext);
var
 LLine: string;
begin
 LLine := Acontext.Connection.IOHandler.ReadLn;
 OutputDebugString(PChar(LLine));
end;
如果要使用终止符,请不要使用
writeln
readln
writeln()
将CRLF追加到传递给它的字符串的末尾,但当它遇到指定的终止符字符串时,
readln()
将停止读取。因此,您正在发送
'Hello | x |#13#10'
,但您只在读取
'Hello | x |'
,将
#13#10
留在套接字缓冲区中,以便下次读取时获取

要解决您的问题,您有两个选择:

1) 如果要继续在
ReadLn()
中使用自定义终止符,请将
WriteLn()
更改为
Write()
,以便不再发送隐式CRLF。
ReadLn()
调用中不需要更改

Write('Hello|x|');
LLine := ReadLn('|x|');
2) 完全停止使用自定义终止符。只将主字符串本身传递给
WriteLn()
,让它附加一个CRLF,然后不要将任何终止符传递给
ReadLn()
,因为它的默认终止符是LF(包括对CRLF的处理)


说到这里,我将编辑Q以包含更好的代码:)谢谢。啊,在不同的线程中使用ShowMessage()是不是很糟糕?事实上,与GUI相关的所有内容都必须通过主线程传递不,还不是这样。我再次编辑了Q以包含您的代码,感谢您让我知道何时/何时不使用ShowMessage()哦,加密/解密函数中包含Base64编码/解码,并且可以正常工作。请问您为什么在发件人代码中使用线程安全列表?这对我来说没有意义。之前创建了未知数量(在编译时)的客户端实例,这会向每个实例发送一个字符串,从而生成Clientlist。
Write('Hello|x|');
LLine := ReadLn('|x|');
WriteLn('Hello');
LLine := ReadLn();