Java基礎(39)——網絡編程相關知識詳解及示例分析六(TCP通信技術詳解及示例)
版權聲明
- 本文原創作者:清風不渡
- 博客地址:https://blog.csdn.net/WXKKang
一、TCP通信
1、TCP通信基礎知識
(1)通信過程
TCP協議用來控制兩個網絡設備之間的點對點通信,兩端設備按作用分爲客戶端和服務端。服務端爲客戶端提供服務,通常等待客戶端的請求消息,有客戶端請求到達後,及時提供服務和返回響應消息;客戶端向服務端主動發出請求,並接收服務的響應消息,它的通信過程步驟如下:
1、首先啓動服務端程序,並開始等待網絡中的客戶端請求,然後客戶端主動向服務端發出連接請求,服務端接收到客戶端的連接請求後,將和客戶端之間建立一個穩定的TCP/IP通信的連接。
2、現在客戶端將向服務端主動發出請求,服務端接收客戶端消息,並及時返回響應消息。這是通過I/O流(字節流)實現的
3、通信完成後,由客戶端主動關閉和服務端之間的連接;如果客戶端未主動關閉和服務端之間的連接,服務端在等待指定的時間後將會自動關閉這個連接
(2)TCP通信的特點
TCP是Tranfer Control Protocol的簡稱,是一種面向連接的保證可靠傳輸的協議。通過TCP協議傳輸,得到的是一個順序的無差錯的數據流。發送方和接收方的成對的兩個socket之間必須建立連接,以便在TCP協議的基礎上進行通信,當一個socket (通常都是server socket)等待建立連接時,另一個socket可以要求進行連接,一旦這兩個socket連接起來,它們就可以進行雙向數據傳輸,雙方都可以進行發送或接收操作。TCP通訊類似於打電話,必須雙方把電話接通後,才能進行通話,任何一方斷線都會造成無法進行通話,須再次連接
(3)Socket和ServerSocket
因爲TCP通信兩端的行爲是不同的,所以在客戶端使用Socket 類實現通信,而服務器使用ServerSocket實現通信
網絡通信不是必須要有兩個物理主機,而是需要有兩個不同的Socket 就可以通信。例如,在同一主機上IP地址是相同的,但是使用不同的端口創建不同的Socket, 這樣的兩個Socket之間也是可以實現TCP/IP通信
(4)TCP通信的實現
無論一個TCP通信程序的功能多麼齊全、程序多麼複雜,其基本結構都是一樣的,都包括以下四個基本步驟:
1、在服務端指定一個端口號來創建ServerSocket,並使用accept 方法進行偵聽,這將阻塞服務器線程,等待用戶請求
2、在客戶端指定服務器的主機IP和端口號來創建Socket,並連接到服務端ServerSocket,現在服務端的accept方法將被喚醒,同時返回一個和客戶端通信的Socket
3、在客戶端和服務端分別使用Socket來獲得網絡通信的輸入/輸出流,並按照一定的通信協議對Socket 進行讀/寫操作
4、在通信完成後,在客戶端和服務端中分別關閉Socket
通常,程序員的主要工作是針對所要完成的功能在第3步進行編程,第1、2、4步對所有的通信程序來說幾乎都是一樣的
1、TCP通信示例
同樣,我們使用TCP通信技術來實現一個簡單的通信,客戶端向服務端發送一個消息“Hello”,服務端接收到客戶端的消息後返回一個消息:“Welcome”,即可,下面我們來就這個示例開始我們的代碼編寫吧 ~ ~
服務端代碼:
package qfbd.com;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/*
原創作者:清風不渡
博客地址:https://blog.csdn.net/WXKKang
*/
public class Server {
public static void main(String[] args) {
ServerSocket server = null;
Socket socket = null;
try {
server = new ServerSocket(4444);
//等待客戶端連接
socket = server.accept();
//從socket中獲取網絡流
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
//接收客戶端消息
System.out.println("從客戶端接收到的消息爲:"+dataInputStream.readUTF());
//向客戶端返回消息
dataOutputStream.writeUTF("Welcome!!!");
//如果不調用此函數則消息可能發送不成功,因爲緩衝區未滿
dataOutputStream.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(server!=null){
try {
server.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
客戶端代碼:
package qfbd.com;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
/*
原創作者:清風不渡
博客地址:https://blog.csdn.net/WXKKang
*/
public class Client {
public static void main(String[] args){
Socket socket = null;
try {
socket = new Socket("127.0.0.1",4444);
//從socket中獲取網絡流
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
//向服務端發送消息
dataOutputStream.writeUTF("Hello!!!");
//不調用此方法消息可能會發送不成功,因爲緩衝區未佔滿
dataOutputStream.flush();
//接收服務端回傳的消息
System.out.println("服務器回傳的消息爲:"+dataInputStream.readUTF());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
首先如下執行服務端代碼,讓其進入監聽狀態,然後運行客戶端代碼,執行結果如下:
這樣我們就用Java語言實現了一個簡單的TCP通信,咱們下篇見 ~ ~
古之立大事者,不惟有超世之才,亦必有堅忍不拔之志也