第二章、TCP通信程序
2.1 概述
TCP通信能實現兩臺計算機之間的數據交互,要嚴格區分爲Client和Server。
兩端通信時的步驟:
1、服務端程序,需要事先啓動,等待客戶端的連接。
2、客戶端主動連接服務器端,連接成功才能通信,服務端不能主動連接客戶端。
在Java中,提供了兩個類用於實現TCP:
1、客戶端:java.net.Socket類表示。創建Socket對象,向服務端發出連接請求,服務端響應請求,兩者建立連接開始通信。
2、服務端:java.netServerSocket類表示。創建erverSocket對象,相當於開啓一個服務,並等待客戶端的連接。
2.2 Socket類
該類實現客戶端套接字,套接字指的是兩臺設備之間通訊的端點。
服務器必須明確:
-
多個客戶端同時和服務器進行交互,服務器必須明確和哪個客戶端進行交互。在服務器端有一個方法,叫accept客戶端獲取到請求的客戶端對象。
-
多個客戶端同時和服務器進行交互,就需要使用多個IO流對象。
服務器是沒有IO流的,服務器可以獲取到請求的客戶端對象Socket 使用每個客戶端Socket中提供的IO流和客戶端進行交互 服務器使用客戶端的字節輸入流讀取客戶端發送的數據‘ 服務器使用客戶端的字節輸出流給客戶端回寫數據 總之,服務器使用客戶端的流和客戶端交互
客戶端構造方法
Socket(String host,int port)創建一個流套接字並將其連接到指定主機上的指定端口號
-
參數:
String host:服務器主機的名稱/服務器的IP地址 int port:服務器的端口號
客戶端成員方法
OutputStream getOutputStream() 返回此套接字的輸出流
InputStream getInputStream() 返回此套接字的輸入流
close() 關閉套接字
實現步驟
-
創建一個客戶端對象Socket,構造方法綁定服務器的IP地址和端口號
-
使用Socket對象中的方法getOutputStream()獲取網絡字節輸出流OutputStream對象
-
使用網絡字節輸出流OutputStream對象中的方法write,給服務器發送數據
-
使用Socket對象中的方法getInputStream()獲取網絡字節輸入流InputStream對象
-
使用網絡字節輸入流InputStream對象中的方法read,讀取服務器回寫的數據
-
釋放資源(Socket)
注意
-
客戶端和服務器進行交互,必須使用Socket中提供的網絡流,不能使用自己創建的流對象
-
當我們創建客戶端對象Socket的時候,就會去請求服務器和服務器經過3次握手建立連接通路,這時如果服務器沒有啓動,就會拋出異常,如果啓動就可以進行交互。
代碼
package com.demo;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* TCP通信的客戶端:向服務器發送連接請求,給服務器發送數據,讀取服務器回寫的數據
* 表示客戶端的類:
* java.net.Socket:此類實現客戶端套接字。
* 套接字:包含了IP地址和端口號
*/
public class TCPClient {
public static void main(String[] args) throws IOException {
//1.
Socket socket = new Socket("127.0.0.1",8888);
//2.
OutputStream os = socket.getOutputStream();
//3.
os.write("你好服務器".getBytes());
//4.
InputStream is = socket.getInputStream();
//5.
byte[] bytes = new byte[1024];
int len = is.read(bytes);
System.out.println(new String(bytes,0,len));
//6.
socket.close();
}
}
服務器構造方法
ServerSocket(int port) 創建綁定到特點端口的服務器套接字
服務器成員方法
Socket accept() 偵聽並接受此套接字的連接
實現步驟
-
創建服務器ServerSocket對象和系統要指定的端口號
-
使用ServerSocket對象中的方法accept,獲取到請求的客戶端對象Socket
-
使用Socket對象中的方法getInputStream()獲取網絡字節輸入流InputStream對象
-
使用網絡字節輸入流InputStream對象中的方法read,讀取客戶端發送的數據
-
使用Socket對象中的方法getOutputStream()獲取網絡字節輸出流OutputStream對象
-
使用網絡字節輸出流OutputStream對象中的方法write,給客戶端回寫數據
-
釋放資源(Socket,ServerSocket)
代碼
package com.demo;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* TCP通信的服務器端:接受客戶端的請求,讀取客戶端發送的數據,給客戶端回寫數據
* 表示服務器的類:
* java.net.ServerSocket
*/
public class TCPServer {
public static void main(String[] args) throws IOException {
//1.
ServerSocket server = new ServerSocket(8888);
//2.
Socket socket = server.accept();
//3.
InputStream is = socket.getInputStream();
//4.
byte[] bytes = new byte[1024];
int len = is.read(bytes);
System.out.println(new String(bytes,0,len));
//5.
OutputStream os = socket.getOutputStream();
//6.
os.write("收到謝謝".getBytes());
//7.
socket.close();
server.close();
}
}
先運行服務器端,再運行客戶端,控制檯分別打印;
客戶端:
收到謝謝
服務器端:
你好服務器