JavaTCP和UDP套接字程式設計
在我們剛開始入門Java後端的時候可能你會覺得有點複雜,包含了很多雜七雜八的知識,例如檔案上傳下載,監聽器,JDBC,請求重定向,請求轉發等等(當然也沒有很多),但是我們自己真正的去開發一個小型網站(對安全性一起其他併發不作要求)的時候,其實我們會發現,Java後端是真的省事,好像除了CURD還是CURD,沒有什麼更新鮮的了。但是我們回顧計算機網路的知識提出疑問,計算機資訊傳輸有TCP和UDP兩種連線方式,但是我們程式設計的時候怎麼沒體現?怎麼回事呢?
我們學JavaWeb的時候估計最熟悉的就是Servlet了,但是追下去其實我們寫的後端Servlet只是實現了一個介面,並沒有在裡面實現什麼方法,且剛開始程式設計的時候,總會到Tomcat資料夾下複製一個Jar包到專案中,我們的專案才可以執行,否則會報錯是不是,所以我們大概可以推測出對於一些網路連線和傳輸都是Tomcat幫我們做了,也就是伺服器幫我們做了,那麼我們在實際的編碼中怎麼通過Java來實現計算機之間的通訊呢?
Java也為我們考慮到了,Java的網路程式設計,也叫作Socket程式設計!
在瞭解網路程式設計之前,我們先了解一下什麼叫套接字,套接字即指同一臺主機內應用層和運輸層之間的介面,由於這個套接字是建立在網路上建立網路應用的可程式設計介面,因此也將套接字稱為應用程式和網路之間的應用程式程式設計介面!
關於TCP和UDP這裡就不作太多介紹了,我們知道TCP是面向連線的,UDP是不面向連線的,TCP可靠,UDP不可靠即可!
我們來設計一個應用來示範一下,流程:
- 客戶機從鍵盤讀取一行字串,並通過套接字傳送到伺服器。
- 伺服器從連線的套接字獲取這行字串,並對其進行修改(將小寫轉為大寫),最後再發回客戶端。
- 客戶機讀取到伺服器傳送的修改後的字串,並輸出到螢幕。
不說太多了,直接上程式碼:
TCPClient:
public class TCPClient {
public static void main(String[] args) throws Exception {
//建立兩個String型別的字串用來發送和接受
String sentence;
String modifiedSentence;
//建立輸入流,用來接受鍵盤輸入
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in ));
//建立一個Socket型別的 clientSocket 用來發起伺服器和客戶機之間的連線
Socket clientSocket = new Socket("hostname",6789);
//建立向伺服器傳送資訊的輸出流
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
//建立輸入流,用來接收來自伺服器的位元組流
BufferedReader inFormServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//讀流資料
sentence = inFromUser.readLine();
//向伺服器傳送sentence的位元組資料
outToServer.writeBytes(sentence + '\n');
//獲取位元組流資料為String
modifiedSentence = inFormServer.readLine();
System.out.println("Form Server :" + modifiedSentence);
}
}
TCPServer:
public class TCPServer {
public static void main(String[] args) throws Exception{
String clientSentence;
String capitalizedSentence;
//伺服器Socket用來建立連線
ServerSocket welcomeSocket = new ServerSocket(6789);
while(true){
//用這個連線來獲取和傳送,自客戶端發的資料流
Socket connectionSocket = welcomeSocket.accept();
//獲取來自客戶端的位元組流
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
//傳送更改後的資料流
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
//讀取位元組成String字串
clientSentence = inFromClient.readLine();
capitalizedSentence = clientSentence.toUpperCase() +'\n';
outToClient.writeBytes(capitalizedSentence);
}
}
}
public class UDPClient {
public static void main(String[] args) throws Exception{
//讀取鍵盤輸入的位元組流
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
//為客戶機建立了一個傳輸資訊的門,但是並沒與向TCP那樣建立連線
DatagramSocket clientSocket = new DatagramSocket();
//這行程式碼呼叫了DNS查詢,查詢主機名對應的IP地址,後面要用這個地址來向伺服器傳送資訊
InetAddress IPAddress = InetAddress.getByName("hostname");
//需要傳送的位元組陣列
byte[] sendData = new byte[1024];
//接受的位元組陣列
byte[] receiveData = new byte[1024];
String sentence = inFromUser.readLine();
//將字串轉為位元組放入sendData
sendData = sentence.getBytes();
//UDP資料報分組,裡面包含想要傳送的內容以及目的地址等資訊
DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length,IPAddress,9876);
//用這個‘門’來發送這個資料包
clientSocket.send(sendPacket);
//獲取資料報分組
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
//用‘門’獲取資料報
clientSocket.receive(receivePacket);
//將獲取的資料報轉為String型別資料
String modifiedSentence = new String(receivePacket.getData());
System.out.println("From Server:" + modifiedSentence);
//關閉這個門
clientSocket.close();
}
}
public class UDPServer {
public static void main(String[] args) throws Exception{
//大意和客戶端程式碼類似
DatagramSocket serverSocket = new DatagramSocket(9876);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while(true){
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
String capitalized = sentence.toUpperCase();
sendData = capitalized.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length,IPAddress,port);
serverSocket.send(sendPacket);
}
}
}
有網路基本常識的朋友應該很好理解上面的程式碼(記錄供以後參考),博主在程式碼中也作了很詳細的註釋,這裡就不在多解釋什麼了,相信通過上面簡單的例子,我們能夠了解Java是如何實現TCP和UDP套接字程式設計。
以上程式碼參考《計算機網路自頂向下方法》,其他為博主的一些粗陋的見解,可能有不全面的地方,如果大神見到,還請賜教!
參考書籍:《計算機網路自頂向下方法》