好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

java基于UDP实现图片群发功能

udp协议(用户数据报协议)是一种不可靠的网络协议,它在通信实例的两端各建立一个socket,但是这两个socket之间并没有虚拟链路,这两个socket只是发送,接收数据报的对象。

udp的优缺点:

1. 因为udp协议是面向非连接的协议,没有建立连接的过程,因此它的通信效率很高。很适合一些即时性很强的应用场景。

2.因为在正式通信前不必与对方先连接,不管对方状态就直接发送,至于对方是否可以收到这些数据内容,udp无法控制,所以说udp是一种不可靠的协议。

3.传输大小限制在64kb以下,这个尤其要注意,在做这个实例的时候,因为没有考虑到这个,直接传了一张大图,结果找了半天的原因。

java使用datagramsocket代表udp协议的socket,它唯一的作用是接收和发送数据报,至于数据究竟发给谁,datagramsocket并不清楚;具体发送的目的地是由datagrampacket自身决定。当client/server程序使用udp协议时,实际上并没有严格的服务器和客户端的区分。通常固定ip地址,固定端口的datagramsocket对象所在程序被称为服务器,因为有固定的ip,端口地址,其他客户端的数据报可以直接发送到服务器上。

接收数据的datagrampacket在实例化时无需指定端口和ip地址,给出数据数据的字节数组以及长度即可。然后调用datagramsocket的receive()方法等待数据报的到来,该方法阻塞线程直到受到一个数据报为止。

发送数据的datagrampacket不同的是,需要给出完整的目的地,包括ip地址和端口,这样数据报才能知道将数据发给谁。当服务器接收到一个datagrampacket对象后,如果想向该数据报的发送者反馈一些消息,但由于udp协议是面向非连接的,所以不知道数据报是谁发送过来的,但程序可以调用datagrampacket的getaddress()(返回一个inetaddress对象,发报的ip地址),getport()(返回发报的端口)和getsocketaddress()(返回一个socketaddress对象,该对象可以同时代表ip地址和端口)。

实现思路:每个客户端启动时都会向服务端发送一个字符串,该字符串代表该客户端已经上线,并在服务端将每个客户端的发报地址(即socketaddress对象)保存在一个set集合中。当点击任意一个上线的客户端的发送图片按钮,该图片数据就会被发送到服务端上,服务端遍历socketaddress集合,并将图片数据转发到每个socketaddress对应的客户端上,就实现了简单的图片群发。具体代码如下:

客户端发送数据报的工具类:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

public class datagramutil

{

  public static final int boadcast_port = 8888 ;

  public static final string dest_ip = "192.168.1.101" ;

  private static final int data_len = 50000 ;

  //定义本程序私聊的socket实例

  private datagramsocket singlesocket = null ;

  //定义接收网络数据的字符数组

  byte [] inbuff = new byte [data_len];

  private handler handler;

 

  //构造器,初始化资源

  public datagramutil(handler handler) throws exception

  {

   this .handler = handler;

   //创建用于私聊的datagramsocket对象

   singlesocket = new datagramsocket();

   new readsingle().start();

  }

 

  //定义单独用户发送消息的方法

  public void sendsingle( byte [] msg)

  {

   try

   {

    datagrampacket packet = new datagrampacket( new byte [ 0 ] , 0 , inetaddress.getbyname(dest_ip) , boadcast_port);

    packet.setdata(msg);

    singlesocket.send(packet);

   }

   catch (ioexception e)

   {

    e.printstacktrace();

   }

  }

 

  //不断地从datagramsocket中读取数据的线程

  class readsingle extends thread

  {

   byte [] singlebuff = new byte [data_len];

   private datagrampacket singlepacket = new datagrampacket(singlebuff , singlebuff.length);

 

   @override

   public void run()

   {

    while ( true )

    {

     // 读取socket中的数据

     try

     {

      //读取socket中的数据

      singlesocket.receive(singlepacket);

      //处理得到的消息

      message msg = new message();

      msg.what = 0x123 ;

      msg.obj = singlebuff;

      handler.sendmessage(msg);

     }

     catch (ioexception e)

     {

      e.printstacktrace();

      if (singlesocket != null )

      {

       //关闭该socket对象

       singlesocket.close();

      }

     }

    }

   }

  }

}

收到服务端发来的图片数据时,使用handler更新ui。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

public class mainactivity extends activity

{

  private button button;

  private imageview img;

  private datagramutil datagramutil;

  handler handler = new handler()

  {

   @override

   public void handlemessage(message msg)

   {

    if (msg.what == 0x123 )

    {

     byte [] result = ( byte []) msg.obj;

     img.setimagebitmap(bitmapfactory.decodebytearray(result , 0 , result.length));

    }

   }

  };

 

  @override

  protected void oncreate(bundle savedinstancestate)

  {

   super .oncreate(savedinstancestate);

   setcontentview(r.layout.main_activity);

   button = (button) findviewbyid(r.id.send_img_all);

   img = (imageview) findviewbyid(r.id.receiver_img);

 

   try

   {

    datagramutil = new datagramutil(handler);

    senddata(stringyobyte());

   }

   catch (exception e)

   {

    e.printstacktrace();

   }

 

   button.setonclicklistener( new view.onclicklistener()

   {

    @override

    public void onclick(view view)

    {

     senddata(bitmaptobyte());

    }

   });

  }

 

  private void senddata( final byte [] msg)

  {

   new thread()

   {

    @override

    public void run()

    {

     datagramutil.sendsingle(msg);

    }

   }.start();

  }

 

  public byte [] bitmaptobyte()

  {

   bitmap bitmap = bitmapfactory.decoderesource(getresources() , r.drawable.wenqing);

   bytearrayoutputstream bytearray = new bytearrayoutputstream();

   bitmap.compress(bitmap.compressformat.png , 100 , bytearray);

   bitmap.recycle();

   return bytearray.tobytearray();

  }

 

  public byte [] stringyobyte()

  {

   string loginstr = "hello" ;

   return loginstr.getbytes();

  }

}

服务端代码(运行该java程序即可):

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

public class udpserver

{

  public static final int port = 8888 ;

  private static final int data_len = 50000 ;

  byte [] inbuff = new byte [data_len];

  private datagrampacket inpacket = new datagrampacket(inbuff , inbuff.length);

  private datagrampacket outpacket;

  private datagramsocket serversocket;

  private set<socketaddress> socketaddresslist = collections.synchronizedset( new hashset<socketaddress>());

 

  public void init() throws ioexception

  {

   serversocket = new datagramsocket(port);

   while ( true )

   {

    serversocket.receive(inpacket);

    string result = new string(inbuff , 0 , inbuff.length);

    if (result.trim().equals( "hello" ))

    {

     socketaddresslist.add(inpacket.getsocketaddress());

    }

    else

    {

     for (iterator<socketaddress> iterator = socketaddresslist.iterator(); iterator.hasnext() ; )

     {

      socketaddress socketaddress = iterator.next();

      outpacket = new datagrampacket(inbuff , inbuff.length , socketaddress);

      serversocket.send(outpacket);

     }

    }

   }

  }

 

  public static void main(string[] args) throws ioexception

  {

   new udpserver().init();

  }

}

这样实现了简单的图片群发的效果。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

原文链接:https://blog.csdn.net/qq_33022345/article/details/53448103

查看更多关于java基于UDP实现图片群发功能的详细内容...

  阅读:18次