JAVA 網路程式設計UDP TCP
UDP協議
UDP是無連線通訊協議,即在資料傳輸時,資料的傳送端和接收端不建立邏輯連線。簡單來說,當一臺計算機向另外一臺計算機發送資料時,傳送端不會確認接收端是否存在,就會發出資料,同樣接收端在收到資料時,也不會向傳送端反饋是否收到資料UDP的交換過程如下圖所示。
優點:使用UDP協議消耗資源小,通訊效率高,所以通常都會用於音訊、視訊和普通資料的傳輸例如視訊會議都使用UDP協議,因為這種情況即使偶爾丟失一兩個資料包,也不會對接收結果產生太大影響。
缺點:UDP的面向無連線性,不能保證資料的完整性,因此在傳輸重要資料時不建議使用UDP協議。
UDP程式碼實現
JDK提供DatagramPacket類(相當於一個集裝箱),用於封裝UDP通訊中傳送或者接收的資料。
提供DatagramSocket類(相當於碼頭),用於傳送和接收DatagramPacket資料包。
實現UDP傳送端程式碼:(傳送的資料、地址、埠號)
/* * 實現UDP資料傳送端 */ import java.net.DatagramSocket; import java.net.InetAddress; import java.io.IOException; import java.net.DatagramPacket; public class UDPsender { public static void main(String[] args) throws IOException { //1.建立資料包物件DatagramPacket,封裝要傳送的資料,地址,埠號 byte[] buffer="第一個UDP程式!".getBytes(); InetAddress inet=InetAddress.getByName("192.168.43.39"); DatagramPacket dp=new DatagramPacket(buffer,buffer.length,inet,5000); //2.建立資料包的傳送物件DatagramSocket DatagramSocket sendSocket=new DatagramSocket(); //3.傳送資料包 sendSocket.send(dp); //4.關閉資源 sendSocket.close(); } }
實現UDP接收端程式碼:(接收的埠號、接收到的資料拆包)
/* * 實現UDP資料接收端 */ import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class UDPreceiver { public static void main(String[] args) throws IOException { //1.建立接收物件DatagramSocket,繫結接收的埠號 DatagramSocket receiveSocket=new DatagramSocket(5000); //2.建立接收資料的空倉庫DatagramPacket byte[] buffer=new byte[1024]; DatagramPacket dp=new DatagramPacket(buffer,1024); //3.接收資料儲存在DatagramPacket物件中 receiveSocket.receive(dp); //4.拆包,獲取DatagramPacket物件的內容 InetAddress ipAddress=dp.getAddress(); String ip=ipAddress.getHostAddress();//獲取傳送端IP地址 int port=dp.getPort();//獲取傳送端埠號 byte[] data=dp.getData();//獲取資料 int length=dp.getLength();//獲取資料長度 String datastr=new String(data,0,length); System.out.println("IP地址:"+ip+"埠號:"+port+" 資料是:"+datastr); //5.關閉資源 receiveSocket.close(); } }
TCP協議
TCP協議是面向連線的通訊協議,即在傳輸資料前先在傳送端和接收端建立邏輯連線,然後再傳輸資料,它提供了兩臺計算機之間可靠無差錯的資料傳輸。在TCP連線中必須要明確客戶端與伺服器端,由客戶端向服務端發出連線請求,每次連線的建立都需要經過“三次握手”。第一次握手,客戶端向伺服器端發出連線請求,等待伺服器確認,第二次握手,伺服器端向客戶端回送一個響應,通知客戶端收到了連線請求,第三次握手,客戶端再次向伺服器端傳送確認資訊,確認連線。整個互動過程如下圖所示。
由於TCP協議的面向連線特性,它可以保證傳輸資料的安全性,所以是一個被廣泛採用的協議。
TCP程式碼實現
TCP通訊是嚴格區分客戶端與伺服器端的,在通訊時,必須先由客戶端去連線伺服器端才能實現通訊,伺服器端不可以主動連線客戶端,並且伺服器端程式需要事先啟動,等待客戶端的連線。
在JDK中提供了兩個類用於實現TCP程式,一個是ServerSocket類,用於表示伺服器端,一個是Socket類,用於表示客戶端。
當客戶端和服務端建立連線後,資料是以IO流的形式進行互動的,從而實現通訊。
實現TCP伺服器程式:
/*
* TCP伺服器程式實現
*/
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args) throws IOException {
//1.建立伺服器ServerSocket物件,指定伺服器埠號
ServerSocket server=new ServerSocket(6000);
//2.開啟伺服器,等待客戶端連線,當客戶端連線後可以獲得連線伺服器的客戶端Socket物件
Socket socket=server.accept();
//3.向客戶端寫資料
OutputStream out=socket.getOutputStream();
out.write("你已經連線上伺服器".getBytes());
//4.讀客戶端資料
InputStream in=socket.getInputStream();
byte[] data=new byte[1024];
int length=in.read(data);
System.out.println(new String(data,0,length));
//5.關閉資源
socket.close();
server.close();
}
}
TCP客戶端程式:
/*
* TCP客戶端程式實現
*/
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class TCPClient {
public static void main(String[] args) throws IOException {
// 1.建立客戶端Socket物件(指定要連線的伺服器地址和埠號)
Socket socket=new Socket("192.168.43.39",6000);
//2.從伺服器讀資料
InputStream in=socket.getInputStream();
byte[] data=new byte[1024];
int length=in.read(data);
System.out.println(new String(data,0,length));
//3.向伺服器寫資料
OutputStream out=socket.getOutputStream();
out.write("Hello server!".getBytes());
//4.關閉資源
socket.close();
}
}