Delphi和C#之间的TCP通信问题

3
我正在尝试使用TCP将文本行从C#客户端发送到Delphi服务器。两者都只在本地主机上运行。 我希望客户端在合适的时间发送文本行,而服务器能够从传入流中一次读取和处理一个文本行。
以下代码可以实现这一点,但仅一次。Delphi备忘录显示“some line of text 1”。之后,C#会返回异常,指出连接已被强制关闭。
如果每次发送文本行时关闭客户端连接并重新建立新连接,则可以实现所需效果。但这样做非常缓慢,不适用于我的预期用途。
我对TCP很陌生,不知道该怎么做!非常感谢任何帮助实现所需结果的帮助。
Delphi服务器代码如下...
procedure TForm1.FormCreate(Sender: TObject);
begin

  Memo1.Lines.Clear;

  //Server initialization
  TcpServer1 := TTcpServer.Create(Self);
  TcpServer1.OnAccept := TcpServer1Accept;
  TcpServer1.LocalPort := IntToStr(DEFAULT_PORT);
  TcpServer1.Active := true;


end; //TForm1.FormCreate procedure ends


procedure TForm1.TcpServer1Accept(Sender: TObject;
  ClientSocket: TCustomIpClient);
var
somestring : string;
begin

    somestring := ClientSocket.Receiveln('#$D#$A');
    Memo1.Lines.Add(somestring);

end; //TForm1.TcpServer1Accept ends

c# code is.............

public static void Main (string[] args)
{

    bool connectionEstablished = false;
    int messageNum = 1;
    TcpClient theclient = new TcpClient();

    //first try establish a successful connection before proceeding
    Console.WriteLine("Waiting for server......");
    while (connectionEstablished == false) {

        connectionEstablished = true;

        try {

            Int32 port = 2501;
            string server = "127.0.0.1"; //the ip of localhost

            theclient = new TcpClient(server, port);

        } catch {

            Console.WriteLine("Could not find AI server");
            connectionEstablished = false;  
        }


    } //while (connectionEstablished == false) ends

    Console.WriteLine("Connected to server");

    ////////////////////////////////////////
    while (true) {

      try 
      {

        string message = "some line of text " + messageNum.ToString() + "#$D#$A";   

        // Translate the passed message into ASCII and store it as a Byte array.
        Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);         

        NetworkStream stream = theclient.GetStream();

        stream.Write(data, 0, data.Length); //working

        messageNum = messageNum + 1;

      }
      catch (ArgumentNullException e) 
      {
        Console.WriteLine("ArgumentNullException: {0}", e);
        Console.WriteLine("\n Press Enter to continue...");
        Console.Read();                             

      } 
      catch (SocketException e) 
      {
        Console.WriteLine("SocketException: {0}", e);
        Console.WriteLine("\n Press Enter to continue...");
        Console.Read();         

      }


        System.Threading.Thread.Sleep(2500);

    } //while (true) ends
    ////////////////////////////////////////////////


}



    }
2个回答

4
在创建TcpClient实例之后,您需要实际执行Connect操作。
您还可以使用IPAddress a = IPAddress.Loopback;来代替环回适配器的IP地址,以避免需要解析它。
try 
{
    Int32 port = 2501;
    string server = "127.0.0.1"; //the ip of localhost
    theclient = new TcpClient();

    theclient.Connect(server,port);
}

连接签名是 public void Connect(string hostname, int port) 或者 public void Connect(IPAddress address, int port),因此始终先是 IP/主机名,其次是端口,而不是反过来。 - Roland Bär
谢谢你的帮助。我尝试了这个,现在出现了一个异常:“连接请求已经被发送到一个已经连接的套接字”。 - gpred
只有在使用不带有端点信息的构造函数创建TcpClient时(例如Paul Farry的示例),才需要调用Connect()方法。但是,当您使用服务器和端口创建TcpClient时,它将自动连接(“TcpClient Constructor(String, Int32):初始化TcpClient类的新实例并连接到指定主机上的指定端口。”)。 - Roland Bär

0

我不知道 Delphi 中 socket 类的确切行为,但在我看来,如果 OnAccept 过程 TForm1.TcpServer1Accept 结束,服务器会关闭连接。因此,您应该在那里使用一个循环,可能带有结束条件:

procedure TForm1.TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient);
var
  somestring : string;
begin
  do
    begin
      somestring := ClientSocket.Receiveln('#$D#$A');
      Memo1.Lines.Add(somestring);
    end;
  while(somestring.length > 0);
end; //TForm1.TcpServer1Accept ends

这不会是有效的Delphi代码,因为我已经很久没有使用Delphi/Pascal了,但我认为你会明白我的意思...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接