TCP簡介
TCP(Transmission Control Protocol 傳輸控制協議)是一種面向連接的、可靠的、基於字節流的傳輸層通信協議,由IETF的RFC 793定義。在簡化的計算機網絡OSI模型中,它完成第四層傳輸層所指定的功能,用戶數據報協議(UDP)是同一層內[1] 另一個重要的傳輸協議。在因特網協議族(Internet protocol suite)中,TCP層是位於IP層之上,應用層之下的中間層。不同主機的應用層之間經常需要可靠的、像管道一樣的連接,但是IP層不提供這樣的流機制,而是提供不可靠的包交換。 [1]
應用層向TCP層發送用於網間傳輸的、用8位字節表示的數據流,然後TCP把數據流分區成適當長度的報文段(通常受該計算機連接的網絡的數據鏈路層的最大傳輸單元( [1] MTU)的限制)。之後TCP把結果包傳給IP層,由它來通過網絡將包傳送給接收端實體 [1] 的TCP層。TCP爲了保證不發生丟包,就給每個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。然後接收端實體對已成功收到的包發回一個相應的確認(ACK);如果發送端實體在合理的往返時延(RTT)內未收到確認,那麼對應的數據包就被假設爲已丟失將會被進行重傳。TCP用一個校驗和函數來檢驗數據是否有錯誤;在發送和接收時都要計算校驗和
下面爲大家介紹Java Socket TCP協議數據傳輸的用法
涉及到的java類
- ServerSocket (服務器)
- Sokcet (客戶端)
- InetSocketAddress (IP、端口信息)
ServerSocket(socket服務端)
1.創建ServerSocket
ServerSocket serverSocket = new ServerSocket(2000);
這樣就創建了一個ServerSocket 監聽給2000端口發送的數據
2.監聽客戶端連接
通過調用serverSocket的accept方法接受客戶端的請求
Socket socket = serverSocket.accept();
accpet方法是一個阻塞方法 只有接到客戶端的連接後,纔會向下繼續執行
返回的對象就是客戶端socket對象(包含客戶端ip,端口port,終端名稱等)
####3.獲取客戶端發送的數據
InputStream is=socket.getInputStream();
byte[] buffer=new byte[1024];
//rLen代表讀取到字節數量
int rLen=is.read(buffer);
socket.getInputStream()方法拿到客戶端的輸入流 用來讀取客戶端發送的數據
創建一個1024個字節的緩衝區用於讀取客戶端發送字節數據,這裏一般需要循環讀取直到rLen的值爲0 說明數據讀取完畢(ps 可以創建一個字節集合存放讀取的的數據)
4.發送數據給客戶端
OutputStream os=socket.getOutputStream();
String responseContent="respones 數據";
//將字符數據轉換成字節數組
byte[] buffer=responseContent.getBytes();
//發送到客戶端
os.write(buffer);
socket.getOutputStream()獲取客戶端的輸出流,用來發送數據給客戶端
下面是完整代碼實現
public static void main(String[] args) throws IOException {
//創建一個server socket
ServerSocket serverSocket = new ServerSocket(2000);
System.out.println("服務器準備就緒..");
System.out.println("服務器信息:IP " + serverSocket.getInetAddress() + " P " + serverSocket.getLocalPort());
//開啓監聽客戶端請求
for (; ; ) {
Socket socket = serverSocket.accept();
ClientHandler clientHandler = new ClientHandler(socket);
clientHandler.start();
}
}
public static class ClientHandler extends Thread {
private final Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
super.run();
System.out.println("新客戶端連接:IP " + socket.getInetAddress() + " P " + socket.getPort());
try {
PrintStream printStream = new PrintStream(socket.getOutputStream());
InputStream inputStream = socket.getInputStream();
BufferedReader socketInput = new BufferedReader(new InputStreamReader(inputStream));
while (true) {
String receiveMsg = socketInput.readLine();
if ("bye".equals(receiveMsg)) {
printStream.println("bye");
break;
} else {
System.out.println(receiveMsg);
printStream.println("server 說:" + receiveMsg.length());
}
}
socketInput.close();
printStream.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println("連接異常斷開");
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("客戶端斷開連接:IP " + socket.getInetAddress() + " P " + socket.getPort());
}
}
Socket客戶端
1.創建並連接SocketServer
//創建一個socket客戶端對象
Socket socket = new Socket();
//連接服務器 ip 端口port 2000 超時時間3000毫米
socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), 2000),3000);
2.獲取輸出流用於發送數據
OutputStream outputStream = socket.getOutputStream();
String requestContent="request 數據";
//將字符數據轉換成字節數組
byte[] buffer=requestContent.getBytes();
//發送到服務器
os.write(buffer);
3.獲取輸入流用於讀取server發送的數據
InputStream is=socket.getInputStream();
byte[] buffer=new byte[1024];
//rLen代表讀取到字節數量
int rLen=is.read(buffer);
拿到server的數據進行處理
下面是客戶端的完整代碼實現
public static void main(String[] args) throws IOException {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), 2000),3000);
System.out.println("發起服務器連接...");
System.out.println("客戶端信息:IP " + socket.getLocalAddress() + " P " + socket.getLocalPort());
System.out.println("服務器信息:IP " + socket.getInetAddress() + " P " + socket.getPort());
try {
send(socket);
} catch (Exception e) {
e.printStackTrace();
System.out.println("異常關閉");
} finally {
socket.close();
System.out.println("客戶端已退出");
}
}
public static void send(Socket socket) throws IOException {
InputStream in = System.in;
//鍵盤輸入流
BufferedReader input = new BufferedReader(new InputStreamReader(in));
InputStream socketInputStream = socket.getInputStream();
BufferedReader socketBufferedReader = new BufferedReader(new InputStreamReader(socketInputStream));
OutputStream outputStream = socket.getOutputStream();
PrintStream printStream = new PrintStream(outputStream);
while (true) {
String request = input.readLine();
printStream.println(request);
String response = socketBufferedReader.readLine();
if ("bye".equals(response)) {
break;
} else {
System.out.println(response);
}
}
input.close();
socketBufferedReader.close();
printStream.close();
}
這就是tcp Java socket api的基本使用
下篇準備給大家講下UDP相關知識以及用法