您的位置:首页 > 编程语言 > Java开发

ddpush 学习之路 14 UdpConnector.java

2015-03-28 12:47 274 查看
大家好 今天我们来学习 ddpush 的 UdpConnector.java 这个类。这个类。是 ddpush 的UDP 服务器的主类。UDP 服务器的 启动 关闭、 UDP消息接受、UDP消息发送 都是要从这个类中开始的。

好了 我们直接来上代码 学习这个类。

//UDP服务器主类
public class UdpConnector {

//UDP服务器Cannel
protected DatagramChannel antenna;//天线
//UDP消息接收处理类
protected Receiver receiver;
//UDP消息发送处理类
protected Sender sender;
//UDP消息接受处理线程
protected Thread receiverThread;
//UDP消息发送处理线程
protected Thread senderThread;
//服务器启动标识
boolean started = false;
//服务器关闭标识
boolean stoped = false;
//UDP端口号
protected int port = PropertyUtil.getPropertyInt("CLIENT_UDP_PORT");

//设置UDP端口号
public void setPort(int port){
this.port = port;
}
//获取UDP端口号
public int getPort(){
return this.port;
}

public void init(){
}

//UDP服务器启动
public void start() throws Exception{
//UDP服务器cannel 在启动之前不能被创建
if(antenna != null){
throw new Exception("antenna is not null, may have run before");
}
//打开UDP通道
antenna = DatagramChannel.open();
//绑定监听端口
antenna.socket().bind(new InetSocketAddress(port));
System.out.println("udp connector port:"+port);
//non-blocking
//非阻塞模式
antenna.configureBlocking(false);
//设置UDP服务器最大接受的数据包大小
antenna.socket().setReceiveBufferSize(1024*1024*PropertyUtil.getPropertyInt("CLIENT_UDP_BUFFER_RECEIVE"));
//设置UDP服务器最大发送数据包大小
antenna.socket().setSendBufferSize(1024*1024*PropertyUtil.getPropertyInt("CLIENT_UDP_BUFFER_SEND"));
System.out.println("udp connector recv buffer size:"+antenna.socket().getReceiveBufferSize());
System.out.println("udp connector send buffer size:"+antenna.socket().getSendBufferSize());

//创建UDP消息接受对象 并初始化
this.receiver = new Receiver(antenna);
this.receiver.init();
//创建UDP消息发送对象 并初始化
this.sender = new Sender(antenna);
this.sender.init();
//用UDP发射器以及接收器对象 创建相应的线程 并启动
this.senderThread = new Thread(sender,"AsynUdpConnector-sender");
this.receiverThread = new Thread(receiver,"AsynUdpConnector-receiver");
this.receiverThread.start();
this.senderThread.start();
}

//停止UDP服务器
public void stop() throws Exception{
//关闭 UDP 消息接受线程
receiver.stop();
//关闭UDP 消息发送线程
sender.stop();
//让UDP消息接受线程和发送线程完成收尾工作
try{
receiverThread.join();
}catch(Exception e){
e.printStackTrace();
}
try{
senderThread.join();
}catch(Exception e){
e.printStackTrace();
}
//关闭UDP服务器连接
try{antenna.socket().close();}catch(Exception e){}
try{antenna.close();}catch(Exception e){}
}

//获取 收到了多少个UDP数据包
public long getInqueueIn(){
return this.receiver.queueIn.longValue();
}

// 获取 取出了多少个收到的UDP消息包
public long getInqueueOut(){
return this.receiver.queueOut.longValue();
}

//获取 要发送的消息个数
public long getOutqueueIn(){
return this.sender.queueIn.longValue();
}

//获取 已经处理的 需要发送的消息个数
public long getOutqueueOut(){
return this.sender.queueOut.longValue();
}

//获取一个客户端发过来的消息
public ClientMessage receive() throws Exception {
//调用 UDP消息接受处理类 的 receive() 函数 获取一个客户端消息
return receiver.receive();
}

//发送一个UDP消息给客户端
public boolean send(ServerMessage message) throws Exception {
//调用 UDP消息发射器类的send() 函数 发射一个UDP消息
return sender.send(message);
}
}


在说这个类之前。我希望大家看看我之前的两篇文章 Sender.java 和 Receiver.java 这两个类的解释 因为在讲解这个类的时候。我们需要串通 Sender.java Receiver.java 这两个类来讲。

好了。我们先说说UdpConnector.java 这个类。大家把上面的代码都看一下。我都做了比较详细的介绍。

我们这里来说一下 ddpush 的UDP 服务器的整体的流程。

首先 UDP 服务器主类 UdpConnector.java 这个类在外部被创建之后 调用 start() 函数 在 start() 函数内部。我们首先打开了UDP通道监听本机的 9966 端口。也就是监听服务器的 9966 端口。

然后将DatagramChannel设置成 非阻塞 模式 之后就根据这个DatagramChannel 创建 Receiver.java Sender.java 这两个类对象。 并初始化。

初始化完成之后。使用Thread 创建者两个类的线程 并 start() 启动这两个类的线程

然后这个类就完成了他启动UDP服务器的使命。

好了。我们现在开始。将 ddpush 的UDP 服务器整体讲解一遍。

首先 创建UdpConnector 类对象 start 在start里我们创建了DatagramChannel 来监听服务器端口。

然后我们将这个 DatagramChannel 对象 传给 Receiver 和 Sender 里。在Receiver里是一个while 的类似死循环的一个结构。Receiver线程一直从 DatagramChannel 里面读取客户端发送的消息。 如果读取到客户端发送的消息 就将客户端发送的消息包装起来 并放入 消息队列中。 当我们外部需要处理这个收到的客户端消息时。 可以使用 Receiver 类提供的 receive() 这个函数 来获取一个 有效的 客户端消息。

然后在Sender 类的线程体里 也是一个类似 while true的死循环。 在这个循环里。一直去检测 是否有需要发送的UDP消息 当 如果有 就将这个UDP消息通过 DatagramChannel 发射出去。 同时这个类中提供了一个 发射UDP 消息的 函数 也就是 Sender 类中的 send(ServerMessage message) 这个函数。当外部需要发射UDP消息时 通过这个send 函数 将udp消息包放入 Sender 类中的 消息队列中 然后Sender 的线程体里的while循环里就会发现这个被放进来的需要发送的UDP消息包。然后就取出这个UDP消息包 并用 DatagramChannel 将这个UDP消息发射出去。

同时 Sender 和 Receiver 发射器 和 接收器 的对象被存放在 UdpConnector 这个类中。外部无法直接获取这两个类对象 做 消息的发送 和获取客户端消息 所以在UdpConnector 这个类中提供了两个 公共的函数。 receive() 函数 该函数就是用来从 Receiver 对象中 取出一个收到的 有效的 客户端消息。 同时 UdpConnector 里也提供了 send(ServerMessage message) 函数。 用来向 Sender 发射器的 待发射消息队列中 增加要发射的消息包。

也就是说 UdpConnector 负责了 Udp服务器的创建工作。然后将 具体的 发射UDP消息 和接收客户端发过来的UDP消息放到了两个线程中去处理。 然后UdpConnector 对外提供了两个函数 发射UDP消息 和 取出一个客户端发送过来的 有效的 UDP消息包

当外部需要发射UDP消息时 就要使用UdpConnector 的 send 函数。来向客户端发射UDP消息。传递过来的 UDP消息包 会被添加到 待发射消息队列中 然后Sender 线程体里就会发现这个待发射的UDP消息包,将他取出、发射。

当外部需要获取 并处理 客户端发送过来的UDP消息时 使用 UdpConnector 的 receive函数 从接收到的 客户端消息队列中 取出一个 有效的 客户端消息 然后在外部处理。

同时UdpConnector 也提供了一些统计的函数

getInqueueIn()

getInqueueOut()

getOutqueueIn()

getOutqueueOut()

大家看我上面的注释就可以了。 我就不在这里复述了。

by brok1n 20150328
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ddpu udp