Sipdroid数据发送流程

整理一下Sipdroid的数据发送流程.

public class SipProvider implements Configurable, TransportListener

实现TransportListener的目的是什么?简单,为了实现回调,SipProvider实现了TransportListener,记住-这个很重要.

数据发送对应的流程对应如下,再这里假设message就是已经生成好了的(实际上的message涉及到很多的协议,搞了很长时候,这会还在犯晕)

SipdroidProvider----UdpTransport-UdpProvider-UdpSocket

UdpSocket拥有我们最直接的两个方法:send  receive,方法原型如下:


  • /** Receives a datagram packet from this socket. */
  • public void receive(UdpPacket pkt) throws java.io.IOException {
  • DatagramPacket dgram = pkt.getDatagramPacket();
  • socket.receive(dgram);
  • pkt.setDatagramPacket(dgram);
  • }
  • /** Sends an UDP packet from this socket. */
  • public void send(UdpPacket pkt) throws java.io.IOException {
  • socket.send(pkt.getDatagramPacket());
  • }

复制代码

UdpProvider拥有UdpSocket,依托UdpSocket来实现数据的收发,但是receive是阻塞的,这个大家详细缘由看我的另一篇文章:
http://www.shouyanwang.org/thread-5-1-1.html

因此UdpProvider必然要继承thread来让自己成为线程:


  • /** The main thread */
  • public void run() {
  • byte[] buf = new byte[BUFFER_SIZE];
  • UdpPacket packet = new UdpPacket(buf, buf.length);//UdpPacket是DataProgramPacket更深层次的一封装
  • Exception error = null;
  • long expire = 0;
  • if (alive_time > 0)
  • expire = System.currentTimeMillis() + alive_time;
  • try {
  • // socket.setSoTimeout(socket_timeout); modified
  • // loop
  • while (!stop) {
  • try {
  • socket.receive(packet);
  • } catch (InterruptedIOException ie) {
  • if (alive_time > 0 && System.currentTimeMillis() > expire)
  • halt();
  • continue;
  • }
  • if (packet.getLength() >= minimum_length) {
  • if (listener != null)
  • listener.onReceivedPacket(this, packet);///严重注意这里
  • if (alive_time > 0)
  • expire = System.currentTimeMillis() + alive_time;
  • }
  • packet = new UdpPacket(buf, buf.length);
  • }
  • } catch (Exception e) {
  • error = e;
  • stop = true;
  • }
  • is_running = false;
  • if (listener != null)
  • listener.onServiceTerminated(this, error);
  • listener = null;
  • }


复制代码

UdpProvider中有一个UdpProviderListener,在UdpProvider进行初始化的时候便指定了

Siproid----UdpTransport-UdpProvider-UdpSocket(仔细看这个初始化的流程图,我给出它们的构造函数)

public UdpProvider(UdpSocket socket, UdpProviderListener listener) //UdpProvider构造函数

public UdpTransport(int port, TransportListener listener)//UdpTransProt构造函数,UdpTransport实现了UdpProviderListener

udp = new UdpTransport(host_port, host_ipaddr, Sipdroid.this);


所以流程是怎么样的呢?
客户端接收到服务器返回的数据后,首先是在UdpProvider的run里面的,上面的红色字体注意没,UdpProvider会用UdpProviderListener进行回调,UdpProviderListener是谁呢,是UdpTransport,因为UdpTransport实现了UdpProviderListener接口,并在自己的构造函数中将自己作为参数传递给了UdpProvider.

好了,数据已经到了UdpTransport手里了,看下面的UdpTransport是如何实现的?


/** When a new UDP datagram is received. */
public void onReceivedPacket(UdpProvider udp, UdpPacket packet) {
  Message msg = new Message(packet);
  msg.setRemoteAddress(packet.getIpAddress().toString());
  msg.setRemotePort(packet.getPort());
  msg.setTransport(PROTO_UDP);
  if (listener != null)
   listener.onReceivedMessage(this, msg);
}


UdpTransport同样只需要调用onReceivedMessage就可以将数据传回给SipProvider呢,这样SipProvider便获得了从服务器返回的信息,然后程序在获得信息后要做的就是对Message解析,并进行适配,确定手机客户端这边怎么来响应。


通俗点说是上级将接口传递给下级,下级在获得数据后便通过该接口将数据返回给上级.

补充下,其实看了上面的分析后大家也能够从侧面推荐下作者的设计意图,必然有类继承UdpTransport来实现更高界别的Transport,在拥有更高界别UdpTransport会话的同时,必然会有对应的更高级别的UdpProvider

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值