idTcpClient 被动接收服务端传递小的做法
在用 indy 写服务器程序,对socket 编程不熟悉呀,伤不起,简单的问题都得想大头
比如想实现消息服务,客户端可以相互之间发送消息(Socket打洞等做法不想),我的想法是,客户端A要发消息给B,把消息发给服务器,服务器进行中转再发给B,这样就存在 B需要被动接收服务器发送过来的消息,
第一种方法:客户端用一个线程不停 ReadLn。对这种方法,我的疑惑是如何区分服务器发送过来的不同类型的消息呀?
第二种方法:是在客户端再创建一个 server,这种方法我觉得相当于每个客户端都是服务器,将来要设端口映射和防火墙得死人,不科学。
昨天晚上我又想了一个方法,由客户端定时发送一个固定消息给服务器,相当于心跳包,在服务器端存储一个发送给各个客户端的数据队列,服务器收到客户端这个心跳消息时,就检查队列,如果有给这个客户端的消息就将其发送过去。
希望各位大侠帮我解释解释这种事情开发的方法,对socket 编程不太熟悉
socet 消息
[解决办法]
楼主可以参考下服务器和客户端交互的例子,有完整代码和运行程序:http://blog.csdn.net/sqldebug_fan/article/details/7881793,这里客户端有使用INDY的TIdTCPClient组件。
[解决办法]
定义通讯结构体包含客户端的一些基本信息,如ID,名称,连接后的 AThread: TIdPeerThread
,以供服务端主动跟客户端通讯使用
一旦有连接,将它保存到Tlist 中,
区分信息,只要定义通讯类型及描述,以WriteBuffer的形式发送数据包,接收后接收后进行处理
[解决办法]
用TTcpClient 和 TTcpServer 就可以了。
[解决办法]
我的疑惑是如何区分服务器发送过来的不同类型的消息呀?
添加通讯协议,譬如@m+'B'表示发给B, @m+'A'表示发给A. 中转时寻找A或B的标识,找到就发送。
[解决办法]
当然用第一种方法,线程里接收,TimeOut 也是必须的。你所顾虑的不同消息类型,如果有不同类型,那就是协议设计有问题了,你总不能又处理字符串又处理二进制数据。如果只有字符串那你就ReadLn,如果二进制数据ReadBuffer 读,那你看协议怎么定了。一般协议都有个固定长度的头,头里有长度,根据长度再读剩余数据
你后面写的心跳包我也觉得有问题。
从理论上来说TCP本身已经保证了通讯正常,心跳包也就无意义,只有意外断网到触发Disconnect中间那段时间的数据可能会收不到,那你应该设计为每条数据都要有返回,服务器没收到返回就认为没发送成功,等B下次连接时再发给B。