欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java基于UDP實現(xiàn)圖片群發(fā)功能

 更新時間:2019年01月05日 16:13:07   作者:Knick_Zhang  
這篇文章主要為大家詳細介紹了java基于UDP實現(xiàn)圖片群發(fā)功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下

UDP協(xié)議(用戶數(shù)據(jù)報協(xié)議)是一種不可靠的網(wǎng)絡協(xié)議,它在通信實例的兩端各建立一個Socket,但是這兩個Socket之間并沒有虛擬鏈路,這兩個Socket只是發(fā)送,接收數(shù)據(jù)報的對象。

UDP的優(yōu)缺點:

1. 因為UDP協(xié)議是面向非連接的協(xié)議,沒有建立連接的過程,因此它的通信效率很高。很適合一些即時性很強的應用場景。

2.因為在正式通信前不必與對方先連接,不管對方狀態(tài)就直接發(fā)送,至于對方是否可以收到這些數(shù)據(jù)內容,UDP無法控制,所以說UDP是一種不可靠的協(xié)議。

3.傳輸大小限制在64KB以下,這個尤其要注意,在做這個實例的時候,因為沒有考慮到這個,直接傳了一張大圖,結果找了半天的原因。

Java使用DatagramSocket代表UDP協(xié)議的Socket,它唯一的作用是接收和發(fā)送數(shù)據(jù)報,至于數(shù)據(jù)究竟發(fā)給誰,DatagramSocket并不清楚;具體發(fā)送的目的地是由DatagramPacket自身決定。當Client/Server程序使用UDP協(xié)議時,實際上并沒有嚴格的服務器和客戶端的區(qū)分。通常固定IP地址,固定端口的DatagramSocket對象所在程序被稱為服務器,因為有固定的IP,端口地址,其他客戶端的數(shù)據(jù)報可以直接發(fā)送到服務器上。

接收數(shù)據(jù)的DatagramPacket在實例化時無需指定端口和IP地址,給出數(shù)據(jù)數(shù)據(jù)的字節(jié)數(shù)組以及長度即可。然后調用DatagramSocket的receive()方法等待數(shù)據(jù)報的到來,該方法阻塞線程直到受到一個數(shù)據(jù)報為止。

發(fā)送數(shù)據(jù)的DatagramPacket不同的是,需要給出完整的目的地,包括IP地址和端口,這樣數(shù)據(jù)報才能知道將數(shù)據(jù)發(fā)給誰。當服務器接收到一個DatagramPacket對象后,如果想向該數(shù)據(jù)報的發(fā)送者反饋一些消息,但由于UDP協(xié)議是面向非連接的,所以不知道數(shù)據(jù)報是誰發(fā)送過來的,但程序可以調用DatagramPacket的getAddress()(返回一個InetAddress對象,發(fā)報的IP地址),getPort()(返回發(fā)報的端口)和getSocketAddress()(返回一個SocketAddress對象,該對象可以同時代表IP地址和端口)。

實現(xiàn)思路:每個客戶端啟動時都會向服務端發(fā)送一個字符串,該字符串代表該客戶端已經上線,并在服務端將每個客戶端的發(fā)報地址(即SocketAddress對象)保存在一個Set集合中。當點擊任意一個上線的客戶端的發(fā)送圖片按鈕,該圖片數(shù)據(jù)就會被發(fā)送到服務端上,服務端遍歷SocketAddress集合,并將圖片數(shù)據(jù)轉發(fā)到每個SocketAddress對應的客戶端上,就實現(xiàn)了簡單的圖片群發(fā)。具體代碼如下:

客戶端發(fā)送數(shù)據(jù)報的工具類:

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;
 //定義接收網(wǎng)絡數(shù)據(jù)的字符數(shù)組
 byte[] inBuff = new byte[DATA_LEN];
 private Handler handler;

 //構造器,初始化資源
 public DatagramUtil(Handler handler) throws Exception
 {
  this.handler = handler;
  //創(chuàng)建用于私聊的DatagramSocket對象
  singleSocket = new DatagramSocket();
  new ReadSingle().start();
 }

 //定義單獨用戶發(fā)送消息的方法
 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中讀取數(shù)據(jù)的線程
 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中的數(shù)據(jù)
    try
    {
     //讀取Socket中的數(shù)據(jù)
     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();
     }
    }
   }
  }
 }
}

收到服務端發(fā)來的圖片數(shù)據(jù)時,使用Handler更新UI。

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程序即可):

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();
 }
}

這樣實現(xiàn)了簡單的圖片群發(fā)的效果。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Java虛擬機類加載器之雙親委派機制模型案例

    Java虛擬機類加載器之雙親委派機制模型案例

    這篇文章主要介紹了Java虛擬機類加載器之雙親委派機制模型案例,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-08-08
  • springboot+zookeeper實現(xiàn)分布式鎖的示例代碼

    springboot+zookeeper實現(xiàn)分布式鎖的示例代碼

    本文主要介紹了springboot+zookeeper實現(xiàn)分布式鎖的示例代碼,文中根據(jù)實例編碼詳細介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • java安全編碼指南之:聲明和初始化說明

    java安全編碼指南之:聲明和初始化說明

    這篇文章主要介紹了java安全編碼指南之:聲明和初始化說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 精致小巧的java相冊制作方法

    精致小巧的java相冊制作方法

    這篇文章主要為大家詳細介紹了精致小巧的java相冊制作方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Mybatis實體類屬性與數(shù)據(jù)庫不一致解決方案

    Mybatis實體類屬性與數(shù)據(jù)庫不一致解決方案

    這篇文章主要介紹了Mybatis實體類屬性與數(shù)據(jù)庫不一致解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • SpringBoot配置文件中敏感信息加密的三種方法

    SpringBoot配置文件中敏感信息加密的三種方法

    當我們將項目部署到服務器上時,一般會在jar包的同級目錄下加上application.yml配置文件,這樣可以在不重新?lián)Q包的情況下修改配置,這種方式存在安全隱患,如果配置文件泄露,就會造成數(shù)據(jù)庫密碼泄露,所以本文給大家介紹了SpringBoot配置文件中敏感信息加密的三種方法
    2024-05-05
  • 關于Java跨域Json字符轉類對象的方法示例

    關于Java跨域Json字符轉類對象的方法示例

    這篇文章主要給大家介紹了關于Java跨域Json字符轉類對象的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2017-11-11
  • Java EasyExcel讀寫excel如何解決poi讀取大文件內存溢出問題

    Java EasyExcel讀寫excel如何解決poi讀取大文件內存溢出問題

    這篇文章主要介紹了Java EasyExcel讀寫excel如何解決poi讀取大文件內存溢出問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • java實現(xiàn)的n*n矩陣求值及求逆矩陣算法示例

    java實現(xiàn)的n*n矩陣求值及求逆矩陣算法示例

    這篇文章主要介紹了java實現(xiàn)的n*n矩陣求值及求逆矩陣算法,結合具體實例形式分析了java基于數(shù)組的矩陣定義、遍歷、運算等相關操作技巧,需要的朋友可以參考下
    2017-09-09
  • MongoDB中ObjectId的誤區(qū)及引起的一系列問題

    MongoDB中ObjectId的誤區(qū)及引起的一系列問題

    這篇文章主要介紹了MongoDB中ObjectId的誤區(qū)及引起的一系列問題,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-12-12

最新評論