这个问题以前有人问过,没有人解决,我在网上查了很久了,都没有找到答案!用Tcpclient连接Tcpserver后,向Tcpserver发送数据,Tcpserver可以接受到数据!但Tcpserver如何向Tcpclient发送数据呢?我用在Tcpserver的Accept事件中传进来的ClientSocket.sendln发送数据,但根本发不出去,TcpClient的Receive事件也不会被出发!!!究竟该怎么办呢??????????是不是这两个控件有问题?
1、Tcpserver怎么向Tcpclient发数据(字符)?
2、Tcpserver的Tcpclient的Receive事件怎么不会被触发?????
1、Tcpserver怎么向Tcpclient发数据(字符)?
2、Tcpserver的Tcpclient的Receive事件怎么不会被触发?????
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;
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;
这句中的items中你要选择哪个线程,可以根据你准备向哪个客户端来确定,如利用客户端IP来查找相应的线程等.我这里使用了第一个线程.
do2008(事情做了,才是事情)Tcpclient在什么地方接受数据呢?我写了一个TThread的子类,在其中启动新线程用Tcpclient.Receivln方法接受数据,数据可以接受到了,可界面却没有了相应。to:
yuti()
我说的是Delphi7自带的Tcpclient和Tcpserver,不是Indy的。
对tcpserver工作原理不懂,就来和使用其他组件一样使用tcpserver,你有的累了。
建议看tcp/ip方面的开发书籍,看懂理论,随便什么工具都一样的。
http://community.csdn.net/Expert/topic/5049/5049057.xml?temp=.23191471、Tcpserver怎么向Tcpclient发数据(字符)?------〉session[i].CSocket.SendText('ok');
2、Tcpserver的Tcpclient的Receive事件怎么不会被触发?????----->ServerSocket接收信息必须有收到来自ClientSocket的信息才能被触发。具体代码在上面的地址里面有。
反正我用着觉得挺方便。。