* UPD傳輸不區分客戶端跟服務端,* 這里用Send和Receive這兩個方法決定誰發誰收
* 1.發送Send * 創建DatagramSocket,隨機端口號* 創建DatagramPacket,指定數據、長度、地址、端口* 創建DatagramSocket發送DatagramPacket* 關閉DatagramSocket
代碼如下:
package com.wsq.socket;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;public class Demo1_Send { //發送端 public static void main(String[] args) throws Exception {String str = "你,陪我度過蟬夏,越過城市喧囂,歌聲還在游走,你榴花般的雙眸,不見你的溫柔,丟失花間歡笑,歲月無法停留,流云的等候~~~"; //所要發送的數據DatagramSocket wsq = new DatagramSocket(); //創建Socket,相當于創建碼頭,端口號可以不指定,可以是隨機端口號;比如,我有倆手機,用哪個手機給你發短信都是可以的DatagramPacket yy = new DatagramPacket(str.getBytes(), str.getBytes().length,InetAddress.getByName("192.168.1.178"),6666);//getByName里面填你要發送人的IP地址和要發送到的端口號//創建Packet,相當于是集裝箱wsq.send(yy); //發貨,將數據發出去,( 碼頭.send(集裝箱) )wsq.close(); //底層是IO流,用完之后也得關掉,關閉碼頭}}
* 2,接收Receive* 創建DatagramSocket,指定端口號 也就是說,去哪個碼頭接貨* 創建DategramPacket,指定數組,長度 接貨的時候,得用箱子去裝* 使用DategramSocket接收DatagramPacket Socket調用receive方法去接收Socket就行了* 關閉DatagramSocket* 從DatagramPacket中獲取數據
代碼如下:
package com.wsq.socket;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class Demo2_Receive { //接收端public static void main(String[] args) throws Exception {DatagramSocket wsq = new DatagramSocket(6666); //創建Socket,相當于創建碼頭,里面添加你想要接收的端口號,也就是去哪個碼頭接貨DatagramPacket yy = new DatagramPacket(new byte[1024], 1024); //創建Packet,相當于創建集裝箱,最好大小匹配 wsq.receive(yy); //接貨,接收數據,數據全在Packet里面;(碼頭.集裝箱)byte [] arr = yy.getData(); //獲取數據,發過來的是一些字節數據,所以要用字節數組來接收//獲取的不是把有效的獲出來,而是把這里面存儲的1024個字節給全部都獲取出來;里面有些是空的沒存東西的,得把有效的字節個數給獲取出來int len = yy.getLength(); //獲取有效的字節個數//知道有效的字節個數了,也知道數據了,然后轉換為對應的字符串System.out.println(new String (arr,0,len)); //arr,0,len;將arr這個數組,從0開始到len結束wsq.close();}}
代碼的運行,這里為了看出效果,在DOS模擬器下運行兩個程序;先運行接收端,再運行發送端
接收端:
發送端:
發送端將
“你,陪我度過蟬夏,越過城市喧囂,歌聲還在游走,你榴花般的雙眸,不見你的溫柔,丟失花間歡笑,歲月無法停留,流云的等候~~~”這個數據,
給發送到接收端,接收端已接收
從這上面的例子可以看出,只能傳遞指定的數據,上面的例子只是傳輸了一句話而已,那要是想要傳輸鍵盤錄入的數據又該怎樣傳輸呢?于是,小編做了些代碼的優化:
package www.wsq.Socket;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;public class Demo1_Send { //發送端public static void main(String[] args) throws Exception {Scanner sc = new Scanner(System.in); //創建鍵盤錄入對象scDatagramSocket wsq = new DatagramSocket(); //創建Socket,相當于創建碼頭,端口號可以不指定,可以是隨機端口號;比如,我有倆手機,用哪個手機給你發短信都是可以的while(true){ //想把數據不斷的發送,這里就定義了一個while循環String line = sc.nextLine(); //不斷地去獲取鍵盤錄入的數據,獲取鍵盤錄入的字符串if("quit".equals(line)){ //對字符串做一個判斷,如果不判斷的話,while這個循環永遠也結束不了,錄入quit,跳出循環break;}DatagramPacket yy = new DatagramPacket(line.getBytes(), line.getBytes().length,InetAddress.getByName("192.168.1.178"),6666);//getByName里面填你要發送人的IP地址和要發送的數據//創建Packet,相當于是集裝箱wsq.send(yy); //發貨,將數據發出去,( 碼頭.send(集裝箱) )} wsq.close(); //底層是IO流,用完之后也得關掉,關閉碼頭}}
package www.wsq.Socket;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class Demo2_Receive { //接收端public static void main(String[] args) throws Exception {DatagramSocket wsq = new DatagramSocket(6666); //創建Socket,相當于創建碼頭,里面添加你想要接收的端口號,也就是去哪個碼頭接貨DatagramPacket yy = new DatagramPacket(new byte[1024], 1024); //創建Packet,相當于創建集裝箱,最好大小匹配 while(true){ //while循環,不斷地去接收數據wsq.receive(yy); //接貨,接收數據,數據全在Packet里面;(碼頭.集裝箱)byte [] arr = yy.getData(); //獲取數據,發過來的是一些字節數據,所以要用字節數組來接收//獲取的不是把有效的獲出來,而是把這里面存儲的1024個字節給全部都獲取出來;里面有些是空的沒存東西的,得把有效的字節個數給獲取出來int len = yy.getLength(); //獲取有效的字節個數/*加個IP地址和端口號,為了看的更加明顯點*/String ip = yy.getAddress().getHostAddress(); //獲取IP地址int port = yy.getPort(); //獲取端口號//知道有效的字節個數了,也知道數據了,然后轉換為對應的字符串System.out.println(ip + ":" + port + ":" + new String (arr,0,len)); //arr,0,len;將arr這個數組,從0開始到len結束//輸出IP地址加端口號加要發送的內容//由于要不斷地接收數據,這里的流就不管了//wsq.close();}}}
這樣就可以實現多數據的發送與接收了
左邊是接收端,右邊是發送端
從這上面兩個例子可以看出,程序運行得啟動兩個DOS模擬器窗口,很麻煩,那,要是想要再一個窗口下執行,又該怎么辦呢?這里就要用到多線程,開啟兩條線程,同時在主線程里面跑,這就可以同時運行,接收的同時再去發送,于是,小編在代碼的優化的基礎上又做了些優化:
package com.wsq.socket;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;public class Demo3_MoreThread {public static void main(String[] args) {new Receive().start(); //開啟線程 new Send().start(); //開啟線程}}class Send extends Thread{public void run(){try {Scanner sc = new Scanner(System.in); //創建鍵盤錄入對象scDatagramSocket wsq = new DatagramSocket(); //創建Socket,相當于創建碼頭,端口號可以不指定,可以是隨機端口號;比如,我有倆手機,用哪個手機給你發短信都是可以的while(true){ //想把數據不斷的發送,這里就定義了一個while循環String line = sc.nextLine(); //不斷地去獲取鍵盤錄入的數據,獲取鍵盤錄入的字符串if("quit".equals(line)){ //對字符串做一個判斷,如果不判斷的話,while這個循環永遠也結束不了,錄入quit,跳出循環break;}DatagramPacket yy = new DatagramPacket(line.getBytes(), line.getBytes().length,InetAddress.getByName("192.168.1.178"),6666);//getByName里面填你要發送人的IP地址和要發送的數據//創建Packet,相當于是集裝箱wsq.send(yy); //發貨,將數據發出去,( 碼頭.send(集裝箱) )} wsq.close(); //底層是IO流,用完之后也得關掉,關閉碼頭} catch (IOException e) {e.printStackTrace();}}
}class Receive extends Thread{public void run(){try {DatagramSocket wsq = new DatagramSocket(6666); //創建Socket,相當于創建碼頭,里面添加你想要接收的端口號,也就是去哪個碼頭接貨DatagramPacket yy = new DatagramPacket(new byte[1024], 1024); //創建Packet,相當于創建集裝箱,最好大小匹配 //只能try,catch捕獲異常,因為在run方法里面不能拋異常while(true){ //while循環,不斷地去接收數據wsq.receive(yy); //接貨,接收數據,數據全在Packet里面;(碼頭.集裝箱)byte [] arr = yy.getData(); //獲取數據,發過來的是一些字節數據,所以要用字節數組來接收//獲取的不是把有效的獲出來,而是把這里面存儲的1024個字節給全部都獲取出來;里面有些是空的沒存東西的,得把有效的字節個數給獲取出來int len = yy.getLength(); //獲取有效的字節個數/*加個IP地址和端口號,為了看的更加明顯點*/String ip = yy.getAddress().getHostAddress(); //獲取IP地址int port = yy.getPort(); //獲取端口號//知道有效的字節個數了,也知道數據了,然后轉換為對應的字符串System.out.println(ip + ":" + port + ":" + new String (arr,0,len)); //arr,0,len;將arr這個數組,從0開始到len結束//輸出IP地址加端口號加要發送的內容//由于要不斷地接收數據,這里的流就不管了//wsq.close();} } catch (IOException e) {e.printStackTrace();}}
}