Client既可主动发送给Server,又可接收到Server的不定时的信息.....怎么设计呀...(20分)

  • 主题发起人 主题发起人 aKnightChen
  • 开始时间 开始时间
A

aKnightChen

Unregistered / Unconfirmed
GUEST, unregistred user!
如果我想用IDTCPServer,IDTCPClient构建这样子的服务器:

1.Client可以主动向Server索取信息(如文件之类)
2.有时,人为操作Server向Client发出指令.

第1个要求我知道怎么做: 就是WriteLn 然后 ReadLn....[阻塞式写法]

但第2个要求我就不会了,
Client怎么知道"什么时候Server发过来指令呢?"
创建一个线程确实可以接收到Server的指令,但它也会截获第1种情景的Serer发送的消息.

哪位大哥有思路,肯请给点提示吧.
 
不如建2条连接,发送消息的连接一直开启,
传文件的连接需要时才连接,
 
一样的呀。当客户端连上后,保存这个连接的ID,然后,SERVER就可以向这个连接发送消息了
 
建立两条线的方法----》此法我也想过,我再等一下,看有没有更好的方法。。。[:)]
 
To: LeonSu[三楼]
保存AThread.Handle,或保存AThread,---目前我就是用这种方法发送消息给客户端
但问题是:关键是客户端接收的问题,它什么时候知道服务器发了消息呢?
 
我看了你用的控件了 没有关于Recive的事件。我对这两个控件不熟悉,那自然是客服端服务端的配套控件,那就必定有接受&发送了。那客服端放一个闲置线程进行心跳似的反复读写。IdTCPClient1.Socket.Recv() 其返回是-1或是接受东西的长度。判断就可以了。要相互通信进行区分出来,可以用简单的握手辨别方式啊,当然不敢谈是握手协议哦。比如:
命令字+命令内容;接可以啊。。。 我常做的方式是用这样的格式进行封包成流发送。 呵呵
 
To webwx:
首先非常谢谢您的热情帮助。[你还专门到DELPHI中看TIDTcpServer的事件].
我也用SocketServer,SocketCliet开发过一套上传下载程序,
里面的各种困难都被我成功地排除了。

可这个Indy就有点怪,你提议说开一个线程,这我也明白,但是,
一旦开了个线程,它会不会将主线程里的 "Server发送来的消息"抢走呢.
比如:主线程也是Readln,闲置的线程也是Readln,二者无法区分.
 
你是说客服端吧。可以说我还没有你了解这两个控件,但我可以问你一下。客服端有没有自动接受消息的事件呢。如果没有。那你就开线程来达到这样的效果啊。
 
To:webwx
没有自动侦听事件!

因为它是采用阻塞式通讯方法!
开线程是可以,但:
主线程也是Readln,闲置的线程也是Readln,二者无法区分.
[比如:当主线程正在和服务器ReadLn,WriteLn时,管理员突然过来点击“请大家退出”的按纽]
 
我粗粗的看了一下。服务端有Execute,那这应该是接受客服端的吧。现在才想起来你说的怎样判断线程是否接受没有,呵呵。原来是判断这里面出发接受消息的线程啊,这控件这点很不错 有点想IOCP了 不过听说Bug挺多的。 我想按照常理,这个线程在接受到消息后,即便是客服端断开了连接,那服务端也会在这个线程结束前来执行Execute的,除非断开是在发送消息前或是消息未发送到前。不过既然执行了Execute,那么消息已经传到。
就证明消息已经在服务端的内存中了。AThread.Connection.Socket.Recv()即可OK;那么此执行后,线程自动Terminate调了。那就出发Disconnection。这是服务端的看法。
客服端吗:你说没有自动监听的事件。那就是说没有自动接受消息的处理过程了。那你开一个线程来自动接受消息。不要放在主线程里面。在这个线程判断是否有消息到的时候,方法很简单的就是跟接受客服端消息的服务端一样的Socket.Recv(),这样来读,每次返回一个Int类型的消息长度。你判断是否长度>0了,然后再开线程来处理这个消息吧。这样接受消息就不冲突。这里面最简单的可能要用到临界区。
 
开一个单独线程,假如主动发送消息的类型有二种,则建立两个事件,主要发送消息时,
对相应TEvent置位即可.
var
EA,EB:TSimpleEvent;

function TMyThread.Execute;
begin
while not Terminated do
begin
ReadLn//读限从服务器发过来的信息设定TimeOut,比如100ms
...
if EA.WaitFor(100)=wrSignaled then
begin
...处理第一种主动发送
end;
if EB.WaitFor(100)=wrSignaled then
begin
...处理第二种主动发送
end;
end;
end;
 
To webwx:
想问一下,Socket中,有没有预读的方法?
[平常咱们一ReadLn,就清除Socket内存中的接收的暂存数据,
我想有没有只读,但不清除的方法]
 
To smokingroom:
我很菜,看不懂你这种方法。
我还是GOOGLE一下你这种方法,看有没有新思路。
对了,你这种方法,有没有完整简单的代码例子?
 
其实我是想:
一边收发聊天信息,一边收发文件!
 
自已顶一下,要是再过一天没结果,我就老老实实结贴!
 
怎么不用UDP呢
 
没,以前用Tcp开发过程序,所以,现在还想再用TCP.
 
平分。
我最好决定采用两条连接的方法。
 
后退
顶部