这个问题以前有人问过,没有人解决,我在网上查了很久了,都没有找到答案!用Tcpclient连接Tcpserver后,向Tcpserver发送数据,Tcpserver可以接受到数据!但Tcpserver如何向Tcpclient发送数据呢?我用在Tcpserver的Accept事件中传进来的ClientSocket.sendln发送数据,但根本发不出去,TcpClient的Receive事件也不会被出发!!!究竟该怎么办呢??????????是不是这两个控件有问题?
1、Tcpserver怎么向Tcpclient发数据(字符)?
2、Tcpserver的Tcpclient的Receive事件怎么不会被触发?????

解决方案 »

  1.   

    1.通过设置TTCPServer的BlockMode属性,可以设定TTCPServer为bmBlocking\bmNonBlocking\bmThreadBlocking这三种通讯模式;bmBlocking    为阻塞模式,以同步的方式进行数据传输,
    bmNonBlocking  非阻塞模式,以异步的方式进行数据传输,
    bmThreadBlocking 线程异步模式,创建一个子线程与TcpClient进行通讯,在线程中以同步的方式传输数据;默认是bmThreadBlocking 模式;2.楼主,应该检查一下你的通讯模式如果是bmBlocking模式,可以OnAccept事件中编写代码 
    procedure TForm1.TcpServer1Accept(Sender: TObject;
      ClientSocket: TCustomIpClient);  //接收tcpclient的数据
      ClientSocket.ReceiveFrom()
      ClientSocket.ReceiveBuf()  //向tcpclient发送数据
      ClientSocket.SendBuf()
      ClientSocket.SendTo()3.如果是bmThreadBlocking模式,可以OnGetThread事件中编写代码 
    procedure TForm1.TcpServer1GetThread(Sender: TObject;
      var ClientSocketThread: TClientSocketThread);
    begin
      ClientSocketThread.ClientSocket.  //接收tcpclient的数据
      ClientSocketThread.ClientSocket.ReceiveFrom()
      ClientSocketThread.ClientSocket.ReceiveBuf()  //向tcpclient发送数据
       ClientSocketThread.ClientSocket.SendBuf()
       ClientSocketThread.ClientSocket.SendTo()end;
      

  2.   

    参考:Delphi6中TTcpserver例子http://www.tomore.com/1/3212.html
      

  3.   

    我是这样实现的:
    type
      PClient   = ^TClient;
      TClient   = record  // 客户端所包含的数据
                    DNS         : String[20];            { Hostname }
                    Connected,                           { Time of connect }
                    LastAction  : TDateTime;             { Time of last transaction }
                    Thread      : Pointer;               { Pointer to thread }
                  end;
       TMyThread = class(TThread)
                   IPName:string;
                   Thread:Pointer;
                   end;
        TCommBlock = record   // the Communication Block used in both parts (Server+Client)
                     Command,
                     MyUserName,                 // the sender of the message
                     Msg,                        // the message itself
                     ReceiverName: string[100];  // name of receiver
                   end;
    .........................
    procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
    var
      NewClient: PClient;
    begin
      GetMem(NewClient, SizeOf(TClient));  NewClient.DNS         := AThread.Connection.LocalName;
      NewClient.Connected   := Now;
      NewClient.LastAction  := NewClient.Connected;
      NewClient.Thread      :=AThread;  AThread.Data:=TObject(NewClient);
      try
        Clients.LockList.Add(NewClient);
      finally
        Clients.UnlockList;
      end;
     LbLog.lines.Add(TimeToStr(Time)+' Connection from "'+NewClient.DNS+'"');
     AThread.Connection.WriteLn('您好:欢迎连接到前置机服务器!');
    end;
    ....................................................
    procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
    var
      ActClient, RecClient: PClient;
      CommBlock, NewCommBlock: TCommBlock;
      RecThread: TIdPeerThread;
      i: Integer;
    begin
      if not AThread.Terminated and AThread.Connection.Connected then
      begin
        AThread.Connection.ReadBuffer (CommBlock, SizeOf (CommBlock));
        ActClient := PClient(AThread.Data);
        ActClient.LastAction := Now;  // update the time of last action    if (CommBlock.Command = 'MESSAGE') or (CommBlock.Command = 'DIALOG') then
        begin  // 'MESSAGE': A message was send - forward or broadcast it
               // 'DIALOG':  A dialog-window shall popup on the recipient's screen
               // it's the same code for both commands...      if CommBlock.ReceiverName = '' then
          begin  // no recipient given - broadcast
            LbLog.Lines.Add (TimeToStr(Time)+' Broadcasting '+CommBlock.Command+': "'+CommBlock.Msg+'"');
            NewCommBlock := CommBlock;  // nothing to change ;-))        with Clients.LockList do
            try
              for i := 0 to Count-1 do  // iterate through client-list
      begin
                RecClient := Items[i];           // get client-object
                RecThread := RecClient.Thread;     // get client-thread out of it
                RecThread.Connection.WriteBuffer(NewCommBlock, SizeOf(NewCommBlock), True);  // send the stuff
              end;
            finally
              Clients.UnlockList;
            end;
          end
          else
          begin  // receiver given - search him and send it to him
            NewCommBlock := CommBlock; // again: nothing to change ;-))
            LbLog.Lines.Add(TimeToStr(Time)+' Sending '+CommBlock.Command+' to "'+CommBlock.ReceiverName+'": "'+CommBlock.Msg+'"');
            with Clients.LockList do
            try
              for i := 0 to Count-1 do
              begin
                RecClient:=Items[i];
                if RecClient.DNS=CommBlock.ReceiverName then  // we don't have a login function so we have to use the DNS (Hostname)
                begin
                  RecThread:=RecClient.Thread;
                  RecThread.Connection.WriteBuffer(NewCommBlock, SizeOf(NewCommBlock), True);
                end;
              end;
            finally
              Clients.UnlockList;
            end;
          end;
        end
        else
        begin  // unknown command given
          LbLog.Lines.Add (TimeToStr(Time)+' Unknown command from "'+CommBlock.MyUserName+'": '+CommBlock.Command);
          NewCommBlock.Command := 'DIALOG';       // the message should popup on the client's screen
          NewCommBlock.MyUserName := '[Server]';  // the server's username
          NewCommBlock.Msg := 'I don''t understand your command: "'+CommBlock.Command+'"';  // the message to show
          NewCommBlock.ReceiverName := '[return-to-sender]'; // unnecessary      AThread.Connection.WriteBuffer (NewCommBlock, SizeOf (NewCommBlock), true);  // and there it goes...
        end;
      end;
    end;
    ...............................................................
    procedure TForm1.IdTCPServer1Disconnect(AThread: TIdPeerThread);
    var
      ActClient: PClient;
    begin
      ActClient := PClient(AThread.Data);
      Lblog.Lines.Add (TimeToStr(Time)+' Disconnect from "'+ActClient^.DNS+'"');
      try
        Clients.LockList.Remove(ActClient);
      finally
        Clients.UnlockList;
      end;
      FreeMem(ActClient);
      AThread.Data := nil;
    end;
    .............................................
    //下面这段代码是在另一个窗体中的,我就实现了从SERVER向CLIENT向字符串的功能.
    procedure TForm2.BitBtn2Click(Sender: TObject);
    var
      MyThread:TMyThread ;
    begin
     MyThread:= myList.items[0];
     TIdPeerThread(MyThread.Thread).Connection.Write('你好,我是服务器');
     SLEEP(10);
     TIdPeerThread(MyThread.Thread).Connection.Write('你已成功发送了消息从服务器到客户端');
     mythread.Terminate;
     mythread:=nil;
    end;
      

  4.   

    MyThread:= myList.items[0];
    这句中的items中你要选择哪个线程,可以根据你准备向哪个客户端来确定,如利用客户端IP来查找相应的线程等.我这里使用了第一个线程.
      

  5.   

    to:
      do2008(事情做了,才是事情)Tcpclient在什么地方接受数据呢?我写了一个TThread的子类,在其中启动新线程用Tcpclient.Receivln方法接受数据,数据可以接受到了,可界面却没有了相应。to:
      yuti() 
    我说的是Delphi7自带的Tcpclient和Tcpserver,不是Indy的。
      

  6.   

    没有搞过socket经验,对于server的socket处理你还是没有理论基础,找个socket理论研究下,对你以后网络开发都有好处,不要急于求成。
    对tcpserver工作原理不懂,就来和使用其他组件一样使用tcpserver,你有的累了。
      

  7.   

    提示下你,client发送连接请求给server,server并不处理与client的连接,只是接受client的连接请求,然后会再建立一个socket(或者称为client)与客户端的client建立真正的连接,这个socket使用的端口号可不是server的端口号阿.
    建议看tcp/ip方面的开发书籍,看懂理论,随便什么工具都一样的。
      

  8.   

    不会吧,delphi版不会这么没落吧,没人知道么?
      

  9.   

    我有回答过这个问题,你搜索一下的帖子有的:
    http://community.csdn.net/Expert/topic/5049/5049057.xml?temp=.23191471、Tcpserver怎么向Tcpclient发数据(字符)?------〉session[i].CSocket.SendText('ok');
    2、Tcpserver的Tcpclient的Receive事件怎么不会被触发?????----->ServerSocket接收信息必须有收到来自ClientSocket的信息才能被触发。具体代码在上面的地址里面有。
      

  10.   

    我用的ServerSocket/ClientSocket来实现的,,使用tcpserver/tcpclient的话,据说刘艺《delphi面向对象编程》第八章,有类似例子。
      

  11.   

    建议楼主使用indy10,比较适合咱们这类小白使用
    反正我用着觉得挺方便。。