在线等待

解决方案 »

  1.   

    delphi中有现成的例子。如下:unit Chatmain;interfaceuses
      Classes, QControls, QStdCtrls, QExtCtrls, QButtons, QForms, Sockets;
    type
      TForm1 = class(TForm)
        memRecv: TMemo;
        Panel1: TPanel;
        memSend: TMemo;
        Panel2: TPanel;
        btnSend: TButton;
        Panel3: TPanel;
        Label1: TLabel;
        edtRemoteHost: TEdit;
        Label2: TLabel;
        edtRemotePort: TEdit;
        Label3: TLabel;
        edtLocalPort: TEdit;
        btnActivateServer: TButton;
        TcpClient1: TTcpClient;
        TcpServer1: TTcpServer;
        procedure btnSendClick(Sender: TObject);
        procedure TcpServer1Accept(sender: TObject;
          ClientSocket: TCustomIpClient);
        procedure btnActivateServerClick(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;  // you must create your own thread to synch
      // writing to a gui component
      TClientDataThread = class(TThread)
      private
      public
        ListBuffer :TStringList;
        TargetList :TStrings;
        procedure synchAddDataToControl;
        constructor Create(CreateSuspended: Boolean);
        procedure Execute; override;
        procedure Terminate;
      end;var
      Form1: TForm1;
      //DataThread: TClientDataThread;implementation{$R *.xfm}//------------- TClientDataThread impl -----------------------------------------
    constructor TClientDataThread.Create(CreateSuspended: Boolean);
    begin
      inherited Create(CreateSuspended);
      FreeOnTerminate := true;
      ListBuffer := TStringList.Create;
    end;procedure TClientDataThread.Terminate;
    begin
      ListBuffer.Free;
      inherited;
    end;procedure TClientDataThread.Execute;
    begin
      Synchronize(synchAddDataToControl);
    end;procedure TClientDataThread.synchAddDataToControl;
    begin
     TargetList.AddStrings(ListBuffer);
    end;
    //------------- end TClientDataThread impl -------------------------------------
    procedure TForm1.btnActivateServerClick(Sender: TObject);
    begin
      TcpServer1.LocalPort := edtLocalPort.Text;
      TcpServer1.Active := True;
    end;         procedure TForm1.btnSendClick(Sender: TObject);
    var
      I: Integer;
    begin
      TcpClient1.RemoteHost := edtRemoteHost.Text;
      TcpClient1.RemotePort := edtRemotePort.Text;
      try
        if TcpClient1.Connect then
          for I := 0 to memSend.Lines.Count - 1 do
          TcpClient1.Sendln(memSend.Lines[I]);
      finally
        TcpClient1.Disconnect;
      end;
    end;procedure TForm1.TcpServer1Accept(sender: TObject;
      ClientSocket: TCustomIpClient);
    var
      s: string;
      DataThread: TClientDataThread;
    begin
      // create thread
      DataThread:= TClientDataThread.Create(true);
      // set the TagetList to the gui list that you
      // with to synch with.
      DataThread.TargetList := memRecv.lines;  // Load the Threads ListBuffer
      DataThread.ListBuffer.Add('*** Connection Accepted ***');
      DataThread.ListBuffer.Add('Remote Host: ' + ClientSocket.LookupHostName(ClientSocket.RemoteHost) +
       ' (' + ClientSocket.RemoteHost + ')');
      DataThread.ListBuffer.Add('===== Begin message =====');
      s := ClientSocket.Receiveln;
      while s <> '' do
      begin
        DataThread.ListBuffer.Add(s);
        s := ClientSocket.Receiveln;
      end;
      DataThread.ListBuffer.Add('===== End of message =====');  // Call Resume which will execute and synch the
      // ListBuffer with the TargetList
      DataThread.Resume;end;end.
      

  2.   

    一楼的,你举的例子只是Client向Server传数据,Server并没有向Client传数据。这个问题,期待中
      

  3.   

    两个文件,各建一个工程用。组件见代码段。TcpServer的BlockMode设为bmThreadBlocking。
    TcpClient的通讯代码主要写在onconnect事件中,操作的Socket,为本身的TcpClient的Name,
    如代码所示。TcpServer的通讯代码主要写在OnAccept事件中,操作Socket为×××Accept给出的
    ClientSocket这个Socket。我也是个新手,试了好久。如果你要传文件,要将文件分片,反复通讯
    进行传输。我也正写中,不能提供例子了。unit client;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Sockets;type
      TClientForm = class(TForm)
        client: TTcpClient;
        server: TTcpServer;
        Button1: TButton;
        openfile: TOpenDialog;
        Memo1: TMemo;
        Button2: TButton;
        SaveDialog1: TSaveDialog;
        close1: TButton;
        Button3: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure close1Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
        procedure clientConnect(Sender: TObject);
      private
        FFN : string;
      public
        { Public declarations }
      end;var
      ClientForm: TClientForm;implementation{$R *.dfm}procedure TClientForm.Button1Click(Sender: TObject);
    begin
       client.Connect;
    end;procedure TClientForm.Button2Click(Sender: TObject);
    begin
       if openfile.Execute then
           FFN := openfile.FileName;
    end;procedure TClientForm.close1Click(Sender: TObject);
    begin
       Close;
    end; procedure TClientForm.Button3Click(Sender: TObject);
    begin
       Server.LocalHost := '127.0.0.1';
       Server.LocalPort := '4500';
       Server.Active := true;
       client.RemoteHost := '192.168.0.1';
       client.RemotePort := '5000';
    end;
    procedure TClientForm.clientConnect(Sender: TObject);
    var
      str : string;
    begin
        client.Sendln('ok');
        str := client.Receiveln();
        memo1.Lines.Add(str);
    end;end.///////////////////unit server;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Sockets;type
      TForm1 = class(TForm)
        client: TTcpClient;
        server: TTcpServer;
        Memo1: TMemo;
        close1: TButton;
        Button3: TButton;
        procedure serverAccept(Sender: TObject; ClientSocket: TCustomIpClient);
        procedure close1Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
      private
        //BufSize : integer;
      public
        { Public declarations }
      end;var
      Form1: TForm1;        implementation{$R *.dfm}procedure TForm1.serverAccept(Sender: TObject;
      ClientSocket: TCustomIpClient);
    var
      str: string;
    begin
      str := ClientSocket.Receiveln();
      memo1.Lines.Add(str);
      if str = 'ok' then
      begin
        ClientSocket.Sendln('zz');
      end;
    end;
    procedure TForm1.Button3Click(Sender: TObject);
    begin
       Server.LocalHost := '192.168.0.1';
       Server.LocalPort := '5000';
       Server.Active := true;
    end;procedure TForm1.close1Click(Sender: TObject);
    begin
       server.Active := false;
       Close;
    end;end.
      

  4.   

    补充,例子中unit client中不要TcpServer组件,即去掉server: TTcpServer;同样unit server中不要TcpClient组件,即去掉client:TTcpClient;
      

  5.   

    晕,以上的代码我全看完了,并没有解决楼主的问题“[菜鸟问题]如何用TcpServer和TcpClient,使Server向Client发送消息”
    虽然在unit server中有ClientSocket.Sendln('zz')这一句,即向客户端TCPClient发送消息,但是在unit client中并没有体现出如何接收server发送回来的“zz”字符!!!d7带的例程也看了,还是不能解决楼主说的问题,即tcpClient如何接收从TCPService发送的信息,恳请高手代码支援,这个问题也是我关心的问题
      

  6.   

    客户端要收的话,在TCPCLIENT的ONRECEIVE事件中写代码即可
      

  7.   

    To:gengxuyong(淡水鱼) ,应该添加哪些代码呀?是不是s := ClientSocket.Receiveln;?
    还有,就算不接收,如果server端传过来一些消息,Tcpclient的OnReceive事件好象没有触发,是为什么?
       还有一个问题,TcpServer是用Sendln来向TcpServer端发信息吗?
        谢谢!
      

  8.   

    这个问题我也刚刚搞清楚。我认为是这样的:TCpServer为了保护多客户(线程)连接、发送问题,在接受完客户的连接后(onAccept事件)就会转换为close_wait状态,等待新的连接请求,此时无法直接和server通讯。
    因此,如果要和TCpServer通讯,发送和接收数据都需要在onAccept事件中完成。
    在客户端,如果要接受服务器发回的信息,必须调用一次TcpClient.Receiveln;然后才能触发onReceive事件。因为它不象ClientSocket自动检查接收缓冲区。