JavaTCP和UDP套接字編程


原文地址:http://www.cnblogs.com/MindMrWang/p/8919890.html
在我們剛開始入門Java后端的時候可能你會覺得有點復雜,包含了很多雜七雜八的知識,例如文件上傳下載,監聽器,JDBC,請求重定向,請求轉發等等(當然也沒有很多),但是我們自己真正的去開發一個小型網站(對安全性一起其他並發不作要求)的時候,其實我們會發現,Java后端是真的省事,好像除了CURD還是CURD,沒有什么更新鮮的了。但是我們回顧計算機網絡的知識提出疑問,計算機信息傳輸有TCP和UDP兩種連接方式,但是我們編程的時候怎么沒體現?怎么回事呢?

我們學JavaWeb的時候估計最熟悉的就是Servlet了,但是追下去其實我們寫的后端Servlet只是實現了一個接口,並沒有在里面實現什么方法,且剛開始編程的時候,總會到Tomcat文件夾下復制一個Jar包到項目中,我們的項目才可以運行,否則會報錯是不是,所以我們大概可以推測出對於一些網絡連接和傳輸都是Tomcat幫我們做了,也就是服務器幫我們做了,那么我們在實際的編碼中怎么通過Java來實現計算機之間的通信呢?
Java也為我們考慮到了,Java的網絡編程,也叫作Socket編程!

在了解網絡編程之前,我們先了解一下什么叫套接字,套接字即指同一台主機內應用層和運輸層之間的接口,由於這個套接字是建立在網絡上建立網絡應用的可編程接口,因此也將套接字稱為應用程序和網絡之間的應用程序編程接口!
這里寫圖片描述

關於TCP和UDP這里就不作太多介紹了,我們知道TCP是面向連接的,UDP是不面向連接的,TCP可靠,UDP不可靠即可!
我們來設計一個應用來示范一下,流程:

  1. 客戶機從鍵盤讀取一行字符串,並通過套接字發送到服務器。
  2. 服務器從連接的套接字獲取這行字符串,並對其進行修改(將小寫轉為大寫),最后再發回客戶端。
  3. 客戶機讀取到服務器發送的修改后的字符串,並輸出到屏幕。

不說太多了,直接上代碼:

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套接字編程。

以上代碼參考《計算機網絡自頂向下方法》,其他為博主的一些粗陋的見解,可能有不全面的地方,如果大神見到,還請賜教!

參考書籍:《計算機網絡自頂向下方法》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM