天天看點

java與網絡(UDP)

1. UDP收發的基本操作

資料報的大小限制在64K之内。

  • 封包的接收
System.out.println("接收方啟動中.....");
// 1、使用DatagramSocket  指定端口 建立接收端
DatagramSocket server =new DatagramSocket(6666); //伺服器端偵聽的端口
// 2、準備容器 封裝成DatagramPacket 包裹
byte[] container =new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3、阻塞式接收包裹receive(DatagramPacket p)
server.receive(packet); //阻塞式
// 4、分析資料
//    byte[]  getData()
//                getLength()
 byte[]  datas =packet.getData();
 int len = packet.getLength();
 System.out.println(new String(datas,0,len));
 
// 5、釋放資源
 server.close();      
  • 封包的發送
System.out.println("發送方啟動中.....");
 // 1、使用DatagramSocket  指定端口 建立發送端
DatagramSocket client =new DatagramSocket(8888); //發送端的源端口
 //2、準備資料 一定轉成位元組數組
String data = "黑夜給了我黑色的眼睛";
byte[] datas = data.getBytes("UTF8"); 
 //3、 封裝成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
    new InetSocketAddress("localhost",6666)); //發送端的目的位址和端口号
//4、發送包裹send(DatagramPacket p) * 
client.send(packet);
// 5、釋放資源
client.close();      
  • 如何在eclipse中開啟多個console視窗
  • java與網絡(UDP)
  • 拖動調整Console視窗的位置,然後釘住
  • java與網絡(UDP)
  • 選擇console控制台視窗

2. UDP收發基本資料類型

  • 封包的接收
System.out.println("接收方啟動中.....");
// 1、使用DatagramSocket  指定端口 建立接收端
DatagramSocket server =new DatagramSocket(6666);
// 2、準備容器 封裝成DatagramPacket 包裹
byte[] container =new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3、阻塞式接收包裹receive(DatagramPacket p)
server.receive(packet); //阻塞式
// 4、分析資料    将位元組數組還原為對應的類型
//    byte[]  getData()
//                getLength()
 byte[]  datas =packet.getData();
 int len = packet.getLength();     
DataInputStream dis =new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
//順序與寫出一緻
String msg = dis.readUTF(); 
int age = dis.readInt();
boolean flag = dis.readBoolean();
char ch = dis.readChar();
System.out.println(msg+"-->"+flag);
// 5、釋放資源
server.close();      
  • 封包的發送
System.out.println("發送方啟動中.....");
 // 1、使用DatagramSocket  指定端口 建立發送端
DatagramSocket client =new DatagramSocket(8888);
 //2、準備資料 一定轉成位元組數組
//寫出
ByteArrayOutputStream baos =new ByteArrayOutputStream();
DataOutputStream dos =new DataOutputStream(new BufferedOutputStream(baos));
//操作資料類型 +資料
dos.writeUTF("編碼辛酸淚");
dos.writeInt(18);
dos.writeBoolean(false);
dos.writeChar('a');
dos.flush();
byte[] datas =baos.toByteArray();  
 //3、 封裝成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
    new InetSocketAddress("localhost",6666));
//4、發送包裹send(DatagramPacket p) * 
client.send(packet);
// 5、釋放資源
client.close();      

3. UDP收發對象

  • 封包的接收
System.out.println("接收方啟動中.....");
// 1、使用DatagramSocket  指定端口 建立接收端
DatagramSocket server =new DatagramSocket(6666);
// 2、準備容器 封裝成DatagramPacket 包裹
byte[] container =new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3、阻塞式接收包裹receive(DatagramPacket p)
server.receive(packet); //阻塞式
// 4、分析資料    将位元組數組還原為對應的類型
 byte[]  datas =packet.getData();
 int len = packet.getLength();     
//讀取 -->反序列化
ObjectInputStream ois =new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
//順序與寫出一緻,對象的資料還原
Object str = ois.readObject();
Object date = ois.readObject();
Object employee = ois.readObject();

if(str instanceof String) {
  String strObj = (String) str;
  System.out.println(strObj);
}
if(date instanceof Date) {
  Date dateObj = (Date) date;
  System.out.println(dateObj);
}
if(employee instanceof Employee) {
  Employee empObj = (Employee) employee;
  System.out.println(empObj.getName()+"-->"+empObj.getSalary());
}
// 5、釋放資源
 server.close();      
  • 封包的發送
System.out.println("發送方啟動中.....");
 // 1、使用DatagramSocket  指定端口 建立發送端
DatagramSocket client =new DatagramSocket(8888);
 //2、準備資料 一定轉成位元組數組
//寫出
ByteArrayOutputStream baos =new ByteArrayOutputStream();
ObjectOutputStream oos =new ObjectOutputStream(new BufferedOutputStream(baos));
//對象
oos.writeObject("我卻用它來尋找光明");
oos.writeObject(new Date());
Employee emp =new Employee("歐陽克",400);
oos.writeObject(emp);
oos.flush();
byte[] datas =baos.toByteArray();  

 //3、 封裝成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
    new InetSocketAddress("localhost",6666));
//4、發送包裹
client.send(packet);
// 5、釋放資源
client.close();      

4. 傳輸檔案(小檔案)

  • 工具類
public class IOUtils {
  /**
   * 1、圖檔讀取到位元組數組
   * 1)、圖檔到程式  FileInputStream
   * 2)、程式到位元組數組  ByteArrayOutputStream
   */
  public static byte[] fileToByteArray(String filePath) {
    //1、建立源與目的地
    File src = new File(filePath);
    byte[] dest =null;
    //2、選擇流
    InputStream  is =null;
    ByteArrayOutputStream baos =null;
    try {
      is =new FileInputStream(src);
      baos = new ByteArrayOutputStream();
      //3、操作 (分段讀取)
      byte[] flush = new byte[1024*10]; //緩沖容器
      int len = -1; //接收長度
      while((len=is.read(flush))!=-1) {
        baos.write(flush,0,len);     //寫出到位元組數組中      
      }    
      baos.flush();
      return baos.toByteArray();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }finally {
      //4、釋放資源
      try {
        if(null!=is) {
          is.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    return null;    
  }
  /**
   * 2、位元組數組寫出到圖檔
   * 1)、位元組數組到程式 ByteArrayInputStream
   * 2)、程式到檔案 FileOutputStream
   */
  public static void byteArrayToFile(byte[] src,String filePath) {
    //1、建立源
    File dest = new File(filePath);
    //2、選擇流
    InputStream  is =null;
    OutputStream os =null;
    try {
      is =new ByteArrayInputStream(src);
      os = new FileOutputStream(dest);
      //3、操作 (分段讀取)
      byte[] flush = new byte[5]; //緩沖容器
      int len = -1; //接收長度
      while((len=is.read(flush))!=-1) {
        os.write(flush,0,len);      //寫出到檔案 
      }    
      os.flush();
    } catch (IOException e) {
      e.printStackTrace();
    }finally {
      //4、釋放資源
      try {
        if (null != os) {
          os.close();
        } 
      } catch (Exception e) {
      }
    }
  }
}      
  • 檔案的接收
System.out.println("接收方啟動中.....");
// 1、使用DatagramSocket  指定端口 建立接收端
DatagramSocket server =new DatagramSocket(6666);
// 2、準備容器 封裝成DatagramPacket 包裹
byte[] container =new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3、阻塞式接收包裹receive(DatagramPacket p)
server.receive(packet); //阻塞式
// 4、分析資料    将位元組數組還原為對應的類型
//    byte[]  getData()
//                getLength()
 byte[]  datas =packet.getData();
 int len = packet.getLength();     
 IOUtils.byteArrayToFile(datas, "src/copy.png");     
// 5、釋放資源
server.close();      
  • 檔案的發送
System.out.println("發送方啟動中.....");
 // 1、使用DatagramSocket  指定端口 建立發送端
DatagramSocket client =new DatagramSocket(8888);
 //2、準備資料 一定轉成位元組數組
byte[] datas =IOUtils.fileToByteArray("src/logo.png");    
 //3、 封裝成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
    new InetSocketAddress("localhost",6666));
//4、發送包裹send(DatagramPacket p) * 
client.send(packet);
// 5、釋放資源
client.close();      

5. 多次發送,多次接收

  • 接收端
System.out.println("接收方啟動中.....");
// 1、使用DatagramSocket  指定端口 建立接收端
DatagramSocket server =new DatagramSocket(6666);

while(true) {
  // 2、準備容器 封裝成DatagramPacket 包裹
  byte[] container =new byte[1024*60];
  DatagramPacket packet = new DatagramPacket(container,0,container.length);
  // 3、阻塞式接收包裹receive(DatagramPacket p)
  server.receive(packet); //阻塞式
  // 4、分析資料
  //    byte[]  getData()
  //                getLength()
   byte[]  datas =packet.getData();
   int len = packet.getLength();
   String data=new String(datas,0,len);
   System.out.println(data);
   if(data.equals("bye")) {
     break;
   }
}
// 5、釋放資源
server.close();      
  • 發送端
System.out.println("發送方啟動中.....");
 // 1、使用DatagramSocket  指定端口 建立發送端
DatagramSocket client =new DatagramSocket(8888);
 //2、準備資料 一定轉成位元組數組
BufferedReader reader =new BufferedReader(new InputStreamReader(System.in));
while(true) {
  String data = reader.readLine();
  byte[] datas = data.getBytes();
   //3、 封裝成DatagramPacket 包裹,需要指定目的地
  DatagramPacket packet =new DatagramPacket(datas,0,datas.length,
      new InetSocketAddress("localhost",6666));
  //4、發送包裹send(DatagramPacket p) * 
  client.send(packet);
  if(data.equals("bye")) {
    break;
  }
}
// 5、釋放資源
client.close();      

6. 全雙工通信

  • 接收器
public class TalkReceive implements Runnable {
  private DatagramSocket server;
  private String from;

  public TalkReceive(int port, String from) {
    this.from = from;
    try {
      server = new DatagramSocket(port);
    } catch (SocketException e) {
      e.printStackTrace();
    }
  }

  @Override
  public void run() {
    while (true) {
      byte[] container = new byte[1024 * 60];
      DatagramPacket packet = new DatagramPacket(container, 0, container.length);
      try {
        server.receive(packet);// 阻塞式接收
        byte[] datas = packet.getData();
        int len = packet.getLength();
        String data = new String(datas, 0, len);
        System.out.println(from + ":" + data);
        if (data.equals("bye")) {
          break;
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    server.close();
  }
}      
  • 發送器
public class TalkSend implements Runnable {
  private DatagramSocket client;
  private BufferedReader reader;
  private String destIP;
  private int destPort;

  public TalkSend(int srcPort, String destIP, int destPort) {
    this.destIP = destIP;
    this.destPort = destPort;
    try {
      client = new DatagramSocket(srcPort);
      reader = new BufferedReader(new InputStreamReader(System.in));
    } catch (SocketException e) {
      e.printStackTrace();
    }
  }

  @Override
  public void run() {
    while (true) {
      String data;
      try {
        data = reader.readLine(); // 阻塞讀取控制台輸入
        byte[] datas = data.getBytes();
        DatagramPacket packet = new DatagramPacket(datas, 0, datas.length,
            new InetSocketAddress(this.destIP, this.destPort));
        client.send(packet);
        if (data.equals("bye")) {
          break;
        }
      } catch (IOException e) {
        e.printStackTrace();
      }

    }
    client.close();
  }

}      
  • 對等通信端(屌絲 )
new Thread(new TalkSend(6100, "localhost", 8847)).start(); // 發送
new Thread(new TalkReceive(8848, "長腿皮褲妹")).start(); // 接收      
  • 對等通信端(長腿皮褲妹)
new Thread(new TalkSend(6120, "localhost", 8848)).start(); // 發送
new Thread(new TalkReceive(8847, "屌絲")).start(); // 接收