服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

教程:在j2me中基于udp协议编程


  在gcf中提供了datagramconnection和datagram两个接口,借助他们我们可以在j2me中基于udp协议开发联网应用程序,在midp2.0中,添加了udpdatagramconnection这个接口。他扩展了datagramconnection并添加了两个方法getlocaladdress()和getlocalport()。我们知道udp服务是不可靠的,如果你希望开发更可靠的联网应用的话可以采用socketconnection,因为tcp服务是面向连接且可靠的。我们还必须清楚地一点是以上所说的各种连接方式都不是midp规范中规定必须实现的。因此在使用之前请参考特定设备的开发文档。midp中只有http连接是必须支持的。
  
  同样,我们要获得datagramconnection的话,必须通过connector的open方法,其中的url应该满足如下的形式。
  
  datagram://localhost:5555 这样的话表示建立了一个客户端模式的连接。在指定ip:localhost和指定端口:5555
  datagram://:5555 这样建立的是一个服务器端模式的连接,在本地的5555端口。
  建立连接后,我们可以通过datagramconnection的newdatagram()方法构造一个datagram,然后调用datagramconnection的send()方法。这样数据报将会发送到指定的接受方。例如你可以构建这个一个负责发送数据的sender类。
  
  package com.siemens.datagramtest;
  
  import javax.microedition.io.datagram;
  import javax.microedition.io.datagramconnection;
  
  public class sender extends thread
  {
  
    private datagramconnection dc;
  
    private string address;
  
    private string message;
  
    public sender(datagramconnection dc)
    {
      this.dc = dc;
      start();
    }
  
    public synchronized void send(string addr, string msg)
    {
      address = addr;
      message = msg;
      notify();
    }
  
    public synchronized void run()
    {
  
      while (true)
      {
  
        // if no client to deal, wait until one connects
        if (message == null)
        {
          try
          {
            wait();
          } catch (interruptedexception e)
          {
          }
        }
  
        try
        {
          byte[] bytes = message.getbytes();
          datagram dg = null;
          // are we a sender thread for the client ? if so then there's
          // no address parameter
          if (address == null)
          {
            dg = dc.newdatagram(bytes, bytes.length);
          } else
          {
            dg = dc.newdatagram(bytes, bytes.length, address);
            system.out.println(address);
          }
          dc.send(dg);
        } catch (exception ioe)
        {
          ioe.printstacktrace();
        }
  
        // completed client handling, return handler to pool and
        // mark for wait
        message = null;
      }
    }
  
  }
  注意联网的时候我们应该在另外一个线程中而不是在主线程中。
  
  服务器端的目的就是启动后监听指定的端口,当客户端连接过来后接受数据并记录下客户端的地址,以便服务器端向客户端发送数据。
  package com.siemens.datagramtest;
  
  import java.io.ioexception;
  
  import javax.microedition.io.connector;
  import javax.microedition.io.datagram;
  import javax.microedition.io.datagramconnection;
  import javax.microedition.io.udpdatagramconnection;
  import javax.microedition.lcdui.alert;
  import javax.microedition.lcdui.alerttype;
  import javax.microedition.lcdui.command;
  import javax.microedition.lcdui.commandlistener;
  import javax.microedition.lcdui.display;
  import javax.microedition.lcdui.displayable;
  import javax.microedition.lcdui.form;
  import javax.microedition.lcdui.stringitem;
  import javax.microedition.lcdui.textfield;
  
  public class server implements runnable, commandlistener
  {
  
    private datagrammidlet parent;
  
    private display display;
  
    private form f;
  
    private stringitem si;
  
    private textfield tf;
  
    private command sendcommand = new command("send", command.item, 1);
  
    sender sender;
  
    private string address;
  
    public server(datagrammidlet m)
    {
      parent = m;
      display = display.getdisplay(parent);
      f = new form("datagram server");
      si = new stringitem("status:", " ");
      tf = new textfield("send:", "", 30, textfield.any);
      f.append(si);
      f.append(tf);
      f.addcommand(sendcommand);
      f.setcommandlistener(this);
      display.setcurrent(f);
    }
  
    public void start()
    {
  
      thread t = new thread(this);
      t.start();
    }
  
    public void run()
    {
      try
      {
  
        si.settext("waiting for connection");
        datagramconnection dc =(datagramconnection)connector.open("datagram://:5555");
  
  
        sender = new sender(dc);
  
        while (true)
        {
          datagram dg = dc.newdatagram(100);
          dc.receive(dg);
          address = dg.getaddress();
          si.settext("message received - "
              + new string(dg.getdata(), 0, dg.getlength()));
  
        }
  
      } catch (ioexception ioe)
      {
        alert a = new alert("server", "port 5000 is already taken.", null,
            alerttype.error);
        a.settimeout(alert.forever);
        a.setcommandlistener(this);
        display.setcurrent(a);
      } catch (exception e)
      {
        e.printstacktrace();
      }
    }
  
    public void commandaction(command c, displayable s)
    {
      if (c == sendcommand && !parent.ispaused())
      {
        if (address == null)
        {
          si.settext("no destination address");
        } else
        {
          sender.send(address, tf.getstring());
        }
      }
      if (c == alert.dismiss_command)
      {
        parent.destroyapp(true);
        parent.notifydestroyed();
      }
    }
  
    public void stop()
    {
    }
  
  }
  
  客户端代码则是建立连接后向服务器端发送数据,并等待接受服务器返回的数据。
  package com.siemens.datagramtest;
  
  import java.io.ioexception;
  
  import javax.microedition.io.connectionnotfoundexception;
  import javax.microedition.io.connector;
  import javax.microedition.io.datagram;
  import javax.microedition.io.datagramconnection;
  import javax.microedition.lcdui.alert;
  import javax.microedition.lcdui.alerttype;
  import javax.microedition.lcdui.command;
  import javax.microedition.lcdui.commandlistener;
  import javax.microedition.lcdui.display;
  import javax.microedition.lcdui.displayable;
  import javax.microedition.lcdui.form;
  import javax.microedition.lcdui.stringitem;
  import javax.microedition.lcdui.textfield;
  
  public class client implements runnable, commandlistener
  {
  
    private da

扫描关注微信公众号