2012-04-15 40 views
2

私には地獄を混乱させるエラーがあります。次のコードは、TidTCPClientからTidTCPServerに行を送信します。初めて実行すると、完全に動作します。 2回目は実行され、その後は毎回、すべての文字列の先頭に改行が追加されます。私は何が欠けていますか?私はあなたのクライアントコードの潜在的な問題を参照してくださいIndy TCP通信と改行

procedure TClientForm.ButtonSendStringClick(Sender: TObject); 
    var 
     I: integer; 
     List: TList; 
    begin 
     List := ClientList.LockList; 
     try 
     for I := 0 to (List.Count- 1) do 
     begin 
      TidTCPClient(List[I]).IOHandler.WriteLn('Hello'+'|x|'); 
     end; 
     finally 
     ClientList.UnlockList; 
     end; 
     Edit1.Text := ''; 
    end; 

    procedure TClientForm.IdTCPServer1Execute(AContext: TIdContext); 
    var 
    LLine: string; 
    begin 
    LLine := Acontext.Connection.IOHandler.ReadLn('|x|'); 
    OutputDebugString(PChar(LLine)); 
    end; 
+0

なぜ送信者コードでスレッドセーフリストを使用しているのですか?それは私にとって意味をなさない。 – whosrdaddy

+0

クライアントインスタンスの未知数(コンパイル時)が以前に作成され、これによりそれぞれがクライアントリストに文字列が送信されます。 –

答えて

3

WriteLn()あなたが渡す文字列の末尾にCRLFを追加を使用していませんそれには、ReadLn()は、指定したターミネータ文字列が検出されると読み取りを停止します。したがって、'Hello|x|#13#10'を送信していますが、'Hello|x|'を読み取るだけで、ソケットバッファには#13#10が残っています。あなたは、ReadLn()でカスタムターミネータを使用し続けるので、暗黙のCRLFはもう送信されませんWriteLn()Write()に変更したい場合は

1):

はあなたの問題を解決するには、次の2つの選択肢があります。 ReadLn()コールで変更する必要はありません。

Write('Hello|x|'); 
LLine := ReadLn('|x|'); 

2)カスタムターミネータを使用しないでください。主な文字列だけをWriteLn()に渡して、CRLFを追加させてから、デフォルトのターミネーターがLF(CRLFの処理を含む)であるため、ターミネーターをReadLn()に渡さないでください。

WriteLn('Hello'); 
LLine := ReadLn(); 
2

(私はそれが奇妙な方法でそれをしない知っているが、クライアントのリストは、完全なコードに必要である)、ClientList.unlocklistはあなたのループの外で実行する必要があります。

サーバーの実行イベントでshowmessageを使用しないでください。これは、メインのGUIスレッドではないため、synchronizeを使用するか、別のログ方法を使用する必要があります。 他の潜在的な問題は、暗号化された文字列にキャリッジリターン文字またはヌル文字(#0)が含まれている可能性があります。その場合、サーバーのメソッドが暗号化文字列全体を読み取ることができず、復号化に失敗します。 これを解決する1つの方法は、base64 encodingを使用することです。問題は、使用しているという事実にある

EDIT

'| xと|'ターミネータをReadLnと組み合わせて使用​​します。あなたは、クライアント側からのwritelnを使用しているので、あなたはターミネータを使用したい場合は、この

procedure TClientForm.IdTCPServer1Execute(AContext: TIdContext); 
var 
LLine: string; 
begin 
LLine := Acontext.Connection.IOHandler.ReadLn; 
OutputDebugString(PChar(LLine)); 
end; 

を行うことができますwritelnreadln

+0

いいえ、まだ同じエラーが発生しています! –

+1

私はあなたのより良いコードを含むようにQを編集します:)ありがとうありがとう。 –

+0

ああ、別のスレッドでShowMessage()を使うのは悪いのですか? –

関連する問題