idTcpClient怎样能收到SERVER发来的消息(100分)

  • 主题发起人 主题发起人 rdy808
  • 开始时间 开始时间
R

rdy808

Unregistered / Unconfirmed
GUEST, unregistred user!
idTcpClient 用线程怎么来解决不断刷新获得SERVER发来的消息?
消息发送的方式是 writebuffer(); readbuffer();
而且不影响速度!
在断开连接的时候怎么来解决那个刷新线程的关闭问题?!
 
问题看的不是很明白
 
就是,我怎么能在C端获得S发来的消息!
我是建一个线程来做,想5秒中 ReadFromstack 得到消息一次
 
不用定时器的话,我怎么来做!
 
在C断来连接的时候,那个5秒中读一次信息的线程怎么解决它?
或者有没有其他方法让 C 每5秒读找一下有没有S发来的信息!
最好能给点例子看看!
 
消息到达会触发read事件,你只要在read事件中写代码处理到达的消息就可以了,正常的连接断开会触发断开事件的,在断开事件中写个标志再在主线程中检查是否要关闭连接。问题确实有点看的不是很明白。具体也不知道你要做什么。
 
你说的不是用 IDTCPCLIENT 控件的吧!?使用 SOCKET的那种吗 !?!?没搞过!
能不能点详细的
 
网络方面的啊,23981160q群,大家一起讨论
 
indy是阻塞的,应该用线程来处理,下面indy9的demo,很能说明问题:
unit ClientFrmMainUnit;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, StdCtrls,
GlobalUnit;

type
TClientFrmMain = class(TForm)
CBClientActive: TCheckBox;
IncomingMessages: TMemo;
Label1: TLabel;
Client: TIdTCPClient;
Label2: TLabel;
EditCommand: TComboBox;
Label3: TLabel;
EditMessage: TEdit;
Label4: TLabel;
EditRecipient: TEdit;
ButtonSend: TButton;

procedure CBClientActiveClick(Sender: TObject);
procedure ButtonSendClick(Sender: TObject);

private

public

end;

TClientHandleThread = class(TThread)
private
CB: TCommBlock;

procedure HandleInput;

protected
procedure Execute; override;

end;

var
ClientFrmMain: TClientFrmMain;
ClientHandleThread: TClientHandleThread; // variable (type see above)

implementation

{$R *.DFM}

procedure TClientHandleThread.HandleInput;
begin
if CB.Command = 'MESSAGE' then
ClientFrmMain.IncomingMessages.Lines.Add (CB.MyUserName + ': ' + CB.Msg)
else
if CB.Command = 'DIALOG' then
MessageDlg ('"'+CB.MyUserName+'" sends you this message:'+#13+CB.Msg, mtInformation, [mbOk], 0)
else // unknown command
MessageDlg('Unknown command "'+CB.Command+'" containing this message:'+#13+CB.Msg, mtError, [mbOk], 0);
end;

procedure TClientHandleThread.Execute;
begin
while not Terminated do
begin
if not ClientFrmMain.Client.Connected then
Terminate
else
try
ClientFrmMain.Client.ReadBuffer(CB, SizeOf (CB));
Synchronize(HandleInput);
except
end;
end;
end;

procedure TClientFrmMain.CBClientActiveClick(Sender: TObject);
begin
if CBClientActive.Checked then
begin
try
Client.Connect(10000); // in Indy < 8.1 leave the parameter away

ClientHandleThread := TClientHandleThread.Create(True);
ClientHandleThread.FreeOnTerminate:=True;
ClientHandleThread.Resume;
except
on E: Exception do MessageDlg ('Error while connecting:'+#13+E.Message, mtError, [mbOk], 0);
end;
end
else
begin
ClientHandleThread.Terminate;
Client.Disconnect;
end;

ButtonSend.Enabled := Client.Connected;
CBClientActive.Checked := Client.Connected;
end;

procedure TClientFrmMain.ButtonSendClick(Sender: TObject);
var
CommBlock : TCommBlock;

begin
CommBlock.Command := EditCommand.Text; // assign the data
CommBlock.MyUserName := Client.LocalName;
CommBlock.Msg := EditMessage.Text;
CommBlock.ReceiverName := EditRecipient.Text;

Client.WriteBuffer (CommBlock, SizeOf (CommBlock), true);
end;

end.
 
procedure TTimeThread.Execute;
begin
while Not Terminated do
begin
if Not FClient.Connected then
begin
Terminate;
end else
begin
Try
FClient.ReadBuffer(FBackMsg,SizeOf(FBackMsg));
SynChronize(MyExec);
except
end;
end;
end;
end;

我在关闭连接的时候关闭线程
IdTCPClient.Disconnect;
TimeThread.Terminate;
但是总是报错
EIdSocketError with message'Socket Error # 10038
Socket operation on non_socket'

我认为是在 FClient.ReadBuffer(FBackMsg,SizeOf(FBackMsg)); 出的错,
在不停的等待S发来的消息时,结束线程,它还在读内存信息,所以回出错。

我的想法是否正确,怎么来解决这个问题?
 
等待中啊/1111
 
逻辑混乱!
先读取栈,然后根据栈返回的字节数读取缓存。
由于TCP/IP为流,需要自己定义数据格式,解决数据包分段或粘连问题。
 
to masm: 由于TCP/IP为流,需要自己定义数据格式,解决数据包分段或粘连问题。

期待更详细的解说~
是否提供点源码?wangpingdejiejie2004@21cn.com
 
数据包是自己定义的,大小是固定的,不用读栈了吧?
什么是粘连问题?
 
在 INDY 9的demo 里面也没有再读栈了!所以我觉得没必要读啊!?!不知道是不是可以
 
等着救命啊/11
 
帮帮忙啊/1
 
假设你要传送10个字节、16个字节两个记录结构
你接收到的序列可能是5、9、5、3、4个字节,这就需要自己还原成10、16字节2个记录结构
具体的可以去看看我写的多线程网络传输,2ccc中有,服务端接收算法就是按照这个目的写的,可作参考。目前新的算法已经完成,不久会放上去。
 
to masm
2ccc 是什么地方啊,哈,我刚来大富翁不是很了解,哈!
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部