国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

基于UDP的網絡通信之屏幕共享

網絡 網絡管理
UDP是一種用途廣泛的網絡傳輸協議,發送方只管發送數據出去,而不管是否能夠送達。

[[119951]]

UDP是一種用途廣泛的網絡傳輸協議,發送方只管發送數據出去,而不管是否能夠送達。

應用范圍:有時候因為網絡問題,接收方可能會丟失部分數據,但是并不影響程序的功能。例如視頻直播的時候有一些數據丟失了,最多就是卡頓一下,并不會造成功能很大的影響。

對于發送者而言,需要有一個發送者的地址與端口,也需要知道要發到哪個地址的哪個端口。同時還需要一個socket傳送數據。

在這里,可以將他們形象的比喻成郵政系統。

發送者就是寄件人,接收者就是收件人,而傳遞著就是郵遞員。

  1. // 創建一個發送者(發件人)   
  2. SocketAddress sender = new InetSocketAddress("127.0.0.1", 912);   
  3. // 創建一個接收者(收件人)   
  4. SocketAddress receiver = new InetSocketAddress("127.0.0.1", 913);   
  5. // 創建一個傳遞者(郵遞員)   
  6. DatagramSocket socket = new DatagramSocket(sender);   

而對于寄件人而言,他需要將要寄的東西用一個包裝裝好,也就是包裹一樣。然后再交給郵遞員送出去。

  1. byte[] msg="Hello!".getBytes();   
  2. DatagramPacket m = new DatagramPacket(msg, msg.length, receiver);   
  3. socket.send(m);   

對于接收者而言,他需要知道去哪里取數據,郵遞員是誰,收到了一個包裹。

  1. // 創建接收對象(收件人)   
  2. SocketAddress receiver = new InetSocketAddress("127.0.0.1", 913);   
  3. // 得到消息接收的socket(郵遞員)   
  4. DatagramSocket socket = new DatagramSocket(receiver);   
  5. // 定義好包裹   
  6. DatagramPacket data = new DatagramPacket(buf, buf.length);   
  7. // 用socket將數據包裹接收進來   
  8. socket.receive(data);    

這其中就需要定義一些協議。

UDP出了上述一對一共享,還可以以組播的方式共享數據,即一對多。

這里以簡單的屏幕分享為例

首先,要明確我們的目的是需要將某臺計算機的屏幕分享給其他人。

也就是將計算機屏幕截圖,再使用局域網組播。

由于每次發送的數組不能過大,所以截取屏幕得到的圖片需要分多次發送出去,等客戶端接收到了再拼成原圖。所以需要一個信息頭來保存圖片的基本信息以便于客戶端收到之后能順利拼回原圖。

關鍵在于如何定義這個信息頭,在接收方我們需要知道發送端傳給我們的圖片是分多少次發送過來的,也要知道總共有多少個字節,還要判斷是不是因為網絡原因有部分數據被丟棄了,那樣的話自然就無法還原數據了。

在這里,我采用的方法是:

信息頭定義如下:

第一個字節為類型,暫時用0表示圖片

第二個字節為數據組數,意思是這張圖片分成了多少次發出去,在客戶端需要收到多少才能pin回來

第三個字節為隨機的一個記號,用來告訴客戶端是否數據丟失了。如果有數據丟失,

則應該丟棄相關的所有數據,不能拼回原圖,則跳過這一幀。

第四個字節為實際要傳輸的數據長度的位數。比如實際上是1234byte,則這個值是4

接下來的n個為長度信息,比如:data[4] = 1;data[5] = 2;data[6] = 3;這就表示長度為1234

每一次都發10000個實際字節數據

加上10個左右的頭部信息。所以每個數組長度都是10010

客戶端接收到消息之后,就要判斷是不是有數據丟失。沒有的話就會拼回原圖并顯示

接收到了這次的數據之后,如果發現前一組丟了部分數據,那么就要將前一組數據全部清空,然后繼續接收#p#

部分代碼如下:

發送者:

  1. package V0913;   
  2.    
  3. import java.awt.Dimension;   
  4. import java.awt.Rectangle;   
  5. import java.awt.Robot;   
  6. import java.awt.Toolkit;   
  7. import java.awt.image.BufferedImage;   
  8. import java.io.BufferedOutputStream;   
  9. import java.io.ByteArrayOutputStream;   
  10. import java.io.File;   
  11. import java.io.FileOutputStream;   
  12. import java.io.IOException;   
  13. import java.net.DatagramPacket;   
  14. import java.net.InetAddress;   
  15. import java.net.MulticastSocket;   
  16. import java.net.UnknownHostException;   
  17. import java.util.ArrayList;   
  18.    
  19. import javax.imageio.ImageIO;   
  20.    
  21. /**  
  22.  * 發送數據的線程  
  23.  *   
  24.  * @author 斌  
  25.  * @2014年9月13日  
  26.  */   
  27. public class SendThread extends Thread {   
  28.    
  29.     InetAddress inetAdd;   
  30.     MulticastSocket cast;   
  31.     byte biaoji = 0;   
  32.    
  33.     public void run() {   
  34.         try {   
  35.             // 創建組播地址   
  36.             inetAdd = InetAddress.getByName("230.0.0.1");   
  37.             // 創建組播的Socket對象   
  38.             cast = new MulticastSocket();   
  39.    
  40.             // 截屏   
  41.             Robot robot = new Robot();   
  42.             Dimension dis = Toolkit.getDefaultToolkit().getScreenSize();   
  43.    
  44.             BufferedImage image;   
  45.             while (Login.connected) {   
  46.                 // 得到屏幕截圖數據   
  47.                 image = robot.createScreenCapture(new Rectangle(dis));   
  48.                 // 將圖片轉換為byte數組   
  49.                 ByteArrayOutputStream baos = new ByteArrayOutputStream();   
  50.                 ImageIO.write(image, "png", baos);   
  51.                 byte[] data = baos.toByteArray();   
  52.    
  53.                 // new BufferedOutputStream(new FileOutputStream(new File(   
  54.                 // "data.txt"))).write(data);   
  55.    
  56.                 send(data);   
  57.                 // // 數據丟失的模擬   
  58.                 // byte dt[] = { 0, 122, 2, 1, 4, 1, 2, 3, 4 };   
  59.                 // DatagramPacket packet = new DatagramPacket(dt, dt.length,   
  60.                 // inetAdd, 9876);   
  61.                 //   
  62.                 // // 將其發送   
  63.                 // try {   
  64.                 // cast.send(packet);   
  65.                 // } catch (IOException e) {   
  66.                 // e.printStackTrace();   
  67.                 // }   
  68.    
  69.                 if (biaoji < 100) {   
  70.                     biaoji++;   
  71.                 } else {   
  72.                     biaoji = 0;   
  73.                 }   
  74.    
  75.                 Thread.sleep(30);   
  76.             }   
  77.         } catch (UnknownHostException e) {   
  78.             e.printStackTrace();   
  79.         } catch (Exception e) {   
  80.             e.printStackTrace();   
  81.         }   
  82.     }   
  83.    
  84.     public void send(byte[] data) {   
  85.         // 將data數組拆分發送   
  86.         long length = data.length;// 數據總長度   
  87.         ArrayList<byte[]> list = new ArrayList<byte[]>();   
  88.         byte size = (byte) (length / 10000 + 1);// 這張圖片有多少組數據數據   
  89.         int j = 0;   
  90.         while (j < size) {   
  91.             byte[] dataTemp;   
  92.             int temp;   
  93.             if (j < size - 1) {   
  94.                 temp = 10000;   
  95.             } else {   
  96.                 temp = (int) (length % 10000);// 最后一次需要的大小   
  97.             }   
  98.             dataTemp = new byte[10010];   
  99.             dataTemp[0] = 0;// 類型   
  100.             dataTemp[1] = biaoji;// 記號,接收方用來判斷是不是丟了數據   
  101.             dataTemp[2] = size;// 總共有多少組數據需要接收   
  102.             dataTemp[3] = getLength(temp);// 數據大小占了數組幾位   
  103.             for (int i = 0; i < dataTemp[3]; i++) {   
  104.                 // 將數據大小保存起來   
  105.                 dataTemp[i + 4] = getElem(temp, i);   
  106.             }   
  107.             // 每次存10000個字節數據   
  108.             for (int i = 0; i < temp; i++) {   
  109.                 dataTemp[i + 4 + dataTemp[3]] = data[j * 10000 + i];   
  110.             }   
  111.    
  112.             list.add(dataTemp);   
  113.             j++;   
  114.         }   
  115.    
  116.         // 循環發送數據   
  117.         for (int i = 0; i < list.size(); i++) {   
  118.             // 將其打包   
  119.             DatagramPacket packet = new DatagramPacket(list.get(i),   
  120.                     list.get(i).length, inetAdd, 9876);   
  121.    
  122.             // 將其發送   
  123.             try {   
  124.                 cast.send(packet);   
  125.             } catch (IOException e) {   
  126.                 e.printStackTrace();   
  127.             }   
  128.         }   
  129.         System.out.println("發送了一張圖片");   
  130.     }   
  131.    
  132.     /**  
  133.      * 獲得一個long的位數  
  134.      *   
  135.      * @param num  
  136.      * @return  
  137.      */   
  138.     private byte getLength(long num) {   
  139.         byte count = 1;   
  140.         while (num / 10 != 0) {   
  141.             num /= 10;   
  142.             count++;   
  143.         }   
  144.         return count;   
  145.     }   
  146.    
  147.     /**  
  148.      * 獲得num中第index位的數字,以0開始計算起始位置  
  149.      *   
  150.      * @param num  
  151.      * @param index  
  152.      * @return  
  153.      */   
  154.     private byte getElem(long num, int index) {   
  155.         int length = getLength(num);   
  156.         // 最后一個   
  157.         if ((index + 1) == length) {   
  158.             return (byte) (num % 10);   
  159.         }   
  160.         long count = num;   
  161.         for (int i = 0; i < length - index - 1; i++) {   
  162.             countcount = count / 10;   
  163.         }   
  164.         countcount = count % 10;   
  165.         return (byte) count;   
  166.     }   
  167. }   

#p#接收者:

  1. package V0913;   
  2.    
  3. import java.io.IOException;   
  4. import java.net.DatagramPacket;   
  5. import java.net.InetAddress;   
  6. import java.net.MulticastSocket;   
  7. import java.util.ArrayList;   
  8.    
  9. import javax.swing.ImageIcon;   
  10.    
  11. /**  
  12.  * 接收數據的線程  
  13.  *   
  14.  * @author 斌  
  15.  * @2014年9月13日  
  16.  */   
  17. public class ReceiveThread extends Thread {   
  18.    
  19.     private MulticastSocket cast;   
  20.    
  21.     public void run() {   
  22.    
  23.         try {   
  24.             // 創建窗口   
  25.             MainUI mu = new MainUI();   
  26.             // 創建socket用來接收數據   
  27.             cast = new MulticastSocket(9876);   
  28.             // 定義組播地址   
  29.             InetAddress inetAdd = InetAddress.getByName("230.0.0.1");   
  30.             // 將socket加入該地址組   
  31.             cast.joinGroup(inetAdd);   
  32.             System.out.println("stratServer");   
  33.             while (mu.connect) {   
  34.                 ImageIcon icon = receive();   
  35.                 // 顯示在窗口上   
  36.                 if (icon != null) {   
  37.                     mu.label.setIcon(icon);   
  38.                     mu.center.repaint();   
  39.                 }   
  40.             }   
  41.         } catch (IOException e) {   
  42.             e.printStackTrace();   
  43.         }   
  44.     }   
  45.    
  46.     public ImageIcon receive() throws IOException {   
  47.    
  48.         ArrayList<byte[]> list = new ArrayList<byte[]>();   
  49.         // 創建數據包對象   
  50.    
  51.         byte dataTemp[] = new byte[10010];   
  52.    
  53.         long alllength = 0;   
  54.    
  55.         DatagramPacket packet = new DatagramPacket(dataTemp, dataTemp.length);   
  56.    
  57.         // 接收數據包   
  58.    
  59.         cast.receive(packet);   
  60.         // 提取頭部信息進行解析,第0個為類型,判斷是否為0,第1個為記號,第2個為多少個數據需要接受,第3個為長度的長度,之后接著長度信息,之后再是數據   
  61.    
  62.         int biaoji = dataTemp[1];   
  63.         byte size = dataTemp[2];   
  64.         alllength += getLength(dataTemp);   
  65.         list.add(dealData(dataTemp));   
  66.    
  67.         for (int i = 1; i < size; i++) {   
  68.             packet = new DatagramPacket(dataTemp, dataTemp.length);   
  69.             // 接收數據包   
  70.             cast.receive(packet);   
  71.             if (biaoji == dataTemp[1]) {   
  72.                 list.add(dealData(dataTemp));   
  73.                 alllength += getLength(dataTemp);   
  74.             } else {   
  75.                 // ***************************************************************************************//   
  76.                 System.out.println("有數據丟了");   
  77.                 // 初始化數據   
  78.                 list.clear();   
  79.                 biaoji = dataTemp[1];   
  80.                 size = dataTemp[2];   
  81.                 i = 0;   
  82.                 list.add(dealData(dataTemp));   
  83.                 alllength = getLength(dataTemp);   
  84.             }   
  85.         }   
  86.         // 將list中的數組全部加到data中去   
  87.         byte data[] = new byte[(int) alllength];   
  88.         for (int i = 0; i < list.size(); i++) {   
  89.             byte t[] = list.get(i);   
  90.             for (int j = 0; j < t.length; j++) {   
  91.                 data[i * 10000 + j] = t[j];   
  92.             }   
  93.         }   
  94.         // new BufferedOutputStream(new FileOutputStream(new File("data.txt")))   
  95.         // .write(data);   
  96.    
  97.         // 將數據還原成圖像   
  98.         ImageIcon icon = new ImageIcon(data);   
  99.         return icon;   
  100.     }   
  101.    
  102.     /**  
  103.      * 處理收到的數據,得到真正需要的數據  
  104.      *   
  105.      * @param dataTemp  
  106.      * @return  
  107.      */   
  108.     public byte[] dealData(byte dataTemp[]) {   
  109.    
  110.         int length = getLength(dataTemp);// 一般為10000   
  111.    
  112.         byte[] data = new byte[length];   
  113.         // 得到了數據長度,之后開始讀數據   
  114.         for (int i = 0; i < length; i++) {   
  115.             data[i] = dataTemp[i + dataTemp[3] + 4];   
  116.         }   
  117.         return data;   
  118.     }   
  119.    
  120.     /**  
  121.      * 獲得實際需要數據的長度  
  122.      *   
  123.      * @param dataTemp  
  124.      * @return  
  125.      */   
  126.     public int getLength(byte dataTemp[]) {   
  127.         byte temp[] = new byte[dataTemp[3]];   
  128.         for (int i = 0; i < dataTemp[3]; i++) {   
  129.             temp[i] = dataTemp[i + 4];   
  130.         }   
  131.    
  132.         return getNum(temp);   
  133.     }   
  134.    
  135.     /**  
  136.      * 根據byte數組合成一個數字 如:{1,2,3,4}合成之后為1234  
  137.      *   
  138.      * @param data  
  139.      * @return  
  140.      */   
  141.     public int getNum(byte data[]) {   
  142.         int temp = 0;   
  143.         for (int i = 0; i < data.length; i++) {   
  144.             temp += data[i] * Math.pow(10, data.length - i - 1);   
  145.         }   
  146.         return temp;   
  147.     }   
  148. }   

#p#運行效果圖如下:

 

 

發送端點擊開始按鈕開始發送截圖

 

 

接收方點擊開始,開始接受數據

 

 

由于在本地上直接測試,所以會出現重疊。程序中使用了jna和platform的透明效果。

責任編輯:林琳 來源: ITeye-博客
相關推薦

2019-04-29 10:26:49

TCP網絡協議網絡通信

2025-04-07 00:55:00

RustUDP編程

2020-07-06 07:52:10

Kubernetes網絡通信

2024-02-20 19:53:57

網絡通信協議

2019-09-25 08:25:49

RPC網絡通信

2013-03-21 11:05:14

2020-11-12 08:52:16

Python

2023-09-18 13:12:00

TCPUDP

2009-08-24 17:20:13

C#網絡通信TCP連接

2010-06-14 19:13:28

網絡通信協議

2010-06-29 10:15:31

局域網故障

2010-06-09 11:57:42

網絡通信協議

2021-08-13 11:27:25

網絡通信數據

2017-01-15 17:44:56

node網絡通信Socket

2025-04-17 01:44:00

2010-07-01 15:45:22

網絡通信協議

2022-12-05 09:25:17

Kubernetes網絡模型網絡通信

2023-03-15 08:17:27

Kafka網絡通信組件

2025-10-11 02:15:00

GPULLM網絡通信

2016-08-25 11:17:16

CaaS華為
點贊
收藏

51CTO技術棧公眾號

亚洲成精国产精品女| 久久女同性恋中文字幕| 国产亚洲一区精品| 在线观看av网站永久| www.欧美亚洲| 日韩欧美一区二区在线观看| 欧美电影免费播放| 91精品国产91久久久久福利| 2019年精品视频自拍| 日韩一区国产二区欧美三区| 免费在线观看污视频| 亚洲成人av一区二区| 日韩男人天堂| 欧美精品一卡| 国产一区二区视频播放| 国产尤物一区二区| www.亚洲在线| 欧美三级视频在线| 免费看成年人视频在线观看 | 精品亚洲自拍| 日韩中文字幕在线播放| 女人天堂av在线播放| 91超碰这里只有精品国产| 少妇激情av一区二区| 日韩欧美精品网址| 免费理论片在线观看播放老| 欧美香蕉大胸在线视频观看| 午夜刺激在线| 亚洲午夜免费福利视频| 秋霞在线观看av| 欧美日韩国产精品| 二区在线观看| 日韩视频在线观看一区二区| av黄色在线| 日韩精品免费视频| 日韩色性视频| 久久久久久久久久久人体| 久久久久97| 国产精品美女久久久免费| 成人毛片在线| 国产99视频精品免费视频36| 羞羞视频在线观看欧美| 中国一级大黄大黄大色毛片| 91在线码无精品| 国产国产国产国产国产国产| 色美美综合视频| 国内激情视频在线观看| 美女av一区二区| 久久密一区二区三区| 激情视频在线观看一区二区三区| 免费不卡在线视频| 99999精品视频| 亚洲国产精品一区二区尤物区| 高清av电影在线观看| 亚洲黄色www网站| 年轻的保姆91精品| 91性高湖久久久久久久久_久久99| 亚洲永久字幕| av观看免费在线| 91成人在线观看喷潮| 欧美日韩国产v| 欧美最猛性xxxxx免费| 99视频+国产日韩欧美| 精品人妻少妇一区二区| 亚洲综合激情小说| 男人天堂亚洲| 性欧美办公室18xxxxhd| 国产精品亚洲产品| 日韩在线xxx| 欧美自拍偷拍午夜视频| 精品福利在线| 91久久国产精品91久久性色| 久久中文在线| 波多野结衣 作品| 中文字幕中文在线不卡住| av资源网在线观看| 一本大道久久a久久精二百| av在线下载| 91精品国产99| 亚洲片区在线| av激情网站| 欧美一级在线视频| 秋霞综合在线视频| 国产欧美欧洲| 99精品视频在线观看免费| 国产主播福利在线| 国模吧一区二区三区| 久久国内精品视频| 免费在线看v| 久久久久久久久爱| 蜜臀久久99精品久久久久久9| 热99这里只有精品| 亚洲第一av色| 免费黄色在线| 亚洲人成在线观| 99久久婷婷| 国产盗摄视频在线观看| 日本二三区不卡| 久久精品国产福利| 日韩一区国产在线观看| 欧美激情在线看| 欧美色999| 成人精品久久久| 欧美极品aⅴ影院| 女人天堂av在线播放| 国产精品毛片一区视频| 久久欧美一区二区| 美女福利一区二区| 99re在线观看| 亚洲综合在线五月| 日本一区二区三区视频在线| 色综合久久88色综合天天提莫| 亚洲欧美韩国综合色| 日本亚洲视频| 亚洲国产精品123| 91精品国产欧美一区二区成人| 好吊妞视频这里有精品| av免费看网址| 91精品国产免费| 亚洲欧美综合国产精品一区| 黑森林福利视频导航| 夜夜嗨av一区二区三区免费区 | 日本三级在线观看网站| 亚洲一区二区三区毛片| 91麻豆.com| yiren22亚洲综合| 久久久久久a亚洲欧洲aⅴ| 最新欧美精品一区二区三区| 人成在线免费网站| 国产三区精品| 精品久久久久久| 日韩免费小视频| 人妻激情另类乱人伦人妻| 欧美日韩国产色站一区二区三区| 欧美在线影院| 九色在线网站| 91视频-88av| 亚洲电影第三页| 亚洲欧洲美洲一区二区三区| 99热com| 久久国产精品偷| 国产精品羞羞答答xxdd | 91国内精品野花午夜精品| 欧美国产激情| 国产超碰在线| 国产这里只有精品| **欧美大码日韩| 日本在线电影一区二区三区| 成人av影视| 91在线观看免费高清| 亚洲va韩国va欧美va| 欧美日韩免费| 嫩草精品影院| 日韩av免费电影| 精品少妇一区二区三区在线播放| 青青草国产精品97视觉盛宴| 麻豆系列在线观看| 日本一区二区三区四区五区六区| 亚洲成人激情在线| 2019国产精品| 2023国产精华国产精品| 亚洲国产精品成人一区二区在线| 日本高清视频精品| 欧美色大人视频| 香蕉视频国产精品| 中文字幕在线播放| 亚洲老头同性xxxxx| 久久伊人蜜桃av一区二区| 日日狠狠久久| 亚洲男人网站| 国产经品一区二区| 精品一区二区电影| av一区二区三区四区| 女厕嘘嘘一区二区在线播放| 濑亚美莉一二区在线视频| 欧美午夜宅男影院| 99热免费精品在线观看| a毛片在线看免费观看| 午夜视频久久久| 亚洲午夜色婷婷在线| 91在线云播放| 亚洲三级精品| 色爱综合区网| 狠狠操第一页| 色噜噜狠狠一区二区三区| 欧美激情欧美激情在线五月| 在线视频欧美区| 91丨九色丨黑人外教| 狠狠入ady亚洲精品经典电影| 久久69成人| yiren22综合网成人| 北条麻妃视频在线| 久久久精彩视频| 欧美激情在线视频二区| 欧美一级片在线看| 最新国产成人在线观看| 另类小说视频一区二区| 日韩久久久久| 日本久久久久| jizz一区二区三区|