java-socket實現TCP編程示例

最近學到java的網絡編程,瞭解到java中對網絡編程提供了豐富的API,一般使用的有InetAddress類,URL類和URLConnection類,再就是使用很頻繁的socket類。

我們使用一個小示例,使用socket建立一個socket客戶端和socket服務器。看看能不能實現通信。

由於服務器對每一個鏈接的客戶端都要做出反應,因此用線程來循環監聽。

第一步寫一個線程類ServerThread,服務器需要提供的服務被封裝到這個類裏了:

public class ServerThread extends Thread {
	//和本線程相關的socket
	Socket socket = null;
	
	public ServerThread(Socket socket){
		this.socket = socket;
	}
	
	//線程需要執行的動作
	public void run(){
		InputStream is=null;
		InputStreamReader isr=null;
		BufferedReader br=null;
		OutputStream os=null;
		PrintWriter pw=null;
		try {
			//獲取輸入流,聆聽客戶端的請求
			is = socket.getInputStream();
			//獲取字節流
			isr = new InputStreamReader(is);//獲取字符流
			br = new BufferedReader(isr);//添加緩衝
			String info = null;
			while((info = br.readLine()) != null){//循環讀取客戶端的信息
				System.out.println("我是服務器,客戶端說:"+info);
			}
			socket.shutdownInput();//關閉輸入流
			
			//獲取輸出流,響應客戶端的請求。
			os = socket.getOutputStream();//獲取字節流
			pw = new PrintWriter(os);//包裝成打印流
			pw.write("歡迎您!");
			pw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			//關閉資源
			try {
				if(pw!=null)	pw.close();
				if(os!=null)	os.close();
				if(br!=null)	br.close();
				if(isr!=null)	isr.close();
				if(is!=null)	is.close();
				if(socket!=null)	socket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

第二步搭建socket服務器。給其指定一個端口(不用0—1023端口的原因是之間的端口是默認給系統佔用的),並保持監聽狀態,當客戶端鏈接上了會創建一個新線程做出行爲響應。新建類socket_server_test

public class Socket_server_test {

	public static void main(String[] args) {
		try {
			//1、創建一個服務器端的socket——serverSocket,指定綁定的端口,並監聽此端口
			ServerSocket serverSocket = new ServerSocket(8888);//1023之前的端口不用
			//2、調用accept()方法開始監聽,等待客戶端的鏈接
			Socket socket=null;
			//記錄所連接的客戶端的數量
			int count = 0;
			System.out.println("*********服務器即將啓動,等待客戶端鏈接**********");
			//循環監聽端口並等待
			while(true){
				socket = serverSocket.accept();
				ServerThread serverThread = new ServerThread(socket);
				serverThread.start();
				count++;//統計連接人數,輸出客戶端數量
				System.out.println("客戶端數量:"+count);
				InetAddress address = socket.getInetAddress();
				System.out.println("當前客戶端的IP爲:"+address.getHostAddress());
			}
			
//			serverSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}


這樣我們再寫一個socket客戶端,如上述代碼所示,這個服務器端會獲取客戶端的IP信息~

新建類socket_client_test

public class Socket_client_test {

	public static void main(String[] args) {
		try {
			//1、創建客戶端socket,指定服務器地址和端口
			Socket socket = new Socket("localhost", 8888);
			//2、獲取輸出流,向服務器發送信息。
			OutputStream os = socket.getOutputStream();//字節輸出流
			PrintWriter pw = new PrintWriter(os);//將輸出流包裝成打印流
			pw.write("用戶名:user,密碼:123456");
			pw.write(" 	");
			pw.write(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));//當前時間
			pw.flush();
			socket.shutdownOutput();
			//3、獲取輸入流,並讀取服務器端的響應信息
			InputStream is = socket.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			String info = null;
			while((info = br.readLine())!=null){
				System.out.println("我是客戶端,服務器說:"+info);
			}
			
			//4、關閉其他資源
			br.close();
			is.close();
			pw.close();
			os.close();
			socket.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


然後在運行時,需要先把server類運行,來爲client類提供服務,否則會報異常~server類運行後再運行client後,服務器控制檯和客戶端控制檯輸出不同

服務器端輸出(IP等信息是從客戶端發來的):


客戶端輸出(“歡迎你”是從服務器端發送來的話語):


在這個例子中,socket用accept()方法監聽端口,用getInputStream和getOutputStream兩個方法來獲取輸入流和輸出流。當然,服務結束後需要關閉相應的流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章