TIdUDPServer 怎么给客户端发消息呢
找了一下午的资料。。嫩是找不到办法。
我想实现, 像QQ那样, 一对一的聊天。 QQ太恶心了, 占资源越来越大。 我也只想和一个朋友进行1对1的文字传输。
TIdUDPClient 向 TIdUDPServer 发消息, 是可以实现了。
现在问题就是, TIdUDPServer 怎么向TIdUDPClient 发送消息。
客户端不映射端口可以吗?
先谢谢了。
[解决办法]
客户端没有独立IP的话, 如果服务端有独立IP或者设置端口映射的话
可以让客户端先发包,路由会给它分配端口的, 服务端保存这个端口 , IP 就可以回包过来了
[解决办法]
通常这样的消息发送有3种情况:
1、是2台机器都不在防火墙后,比如同一个局域网或者都是在公网上(比如都是拨号上网的机器)。
2、是1台机器在防火墙后,一台机器不在防火墙后。
3、2台机器都在防火墙后。
对于第一种情况,那太简单了,直接发送消息就可以了。
第二种情况:
A机器在防火墙后(未作端口映射) B机器在公网上
这时A机器可以随时给B机器发消息。B可以收到。
但是由于A机器前面还有路由器。就必须进行“打洞”操作。
即:A机器先给B机器发送消息,B机器收到消息后,
由于你使用的idUdp控件。在udp控件的UDPRead事件收到A机器发来消息的同时
必须回复一条消息(因为此时A在路由器上连接B机器的洞还未关,消息可以发送过去)
用ABinding.SendTo(ABinding.PeerIP,ABinding.PeerPort,UdpAonline[1],length(UdpAonline))
的方式发送过去。记录A机器的IP地址及端口号。
之后,B到A的洞就打开了。在路由器未关闭之前,可以随时通过这个ip地址和端口号给A机器发送消息。
这个时候,这个端口号会记录在A机器前面的路由器中。
但一定时间不使用这个端口号,路由器会自动丢弃这个记录。
这个时候就需要一个心跳的机制来保证这个端口随时打开了。
也就是A机器定时(比如2分钟,最好是10分钟以内)给服务器发送一条消息(称为心跳包)
服务器每次收到心跳包的时候都在上面说的事件内回复一条消息。这样就可以了。
情况3:
情况2相当于P2S的情况,情况3就相当于P2P了。
这个时候2台机器都不可能直接发消息给对方。需要借助于第三方,一个在公网上的服务器S。
A和B上线时,都给S发送消息。S在收到消息后在获取消息事件中回复条消息,使得打洞成功。
这个时候,A和B分别都可以与S通信。那么通过S就可以获得对方的IP地址和端口号了。
(虽然A和B和都使用相同端口和其他机器通信,但通过路由后可能会临时映射成不同端口号)
在获得对方端口号之后,A可以向B发送一条消息。而此消息很肯能被B的路由器抛弃。
这个时候,A再向S发送消息,告知A端的“洞”已经打开。S此时通知B向A打洞。B发过消息后
同样通知S,S通知A和B两边洞都已经打开可以发送消息了。
此时A和B才可以根据记录的对方端口号来发送消息。
[解决办法]