一.TCP通信概述
TCP協議是面向連接的通信協議,在傳輸數據之前,發送端和接收端必須建立邏輯連接,然后再傳輸數據,它提供了兩台計算機之間可靠無差錯的數據傳輸。
在TCP連接中必須要明確客戶端與服務器端,由客戶端向服務端發出連接請求,每次連接的創建都需要經過三次握手。
三次握手:TCP協議中,在發送數據的准備階段,客戶端與服務器之間的三次交互,以保證連接的可靠。
·第一次握手,客戶端向服務器端發出連接請求,等待服務器確認。
·第二次握手,服務器端向客戶端回送一個響應,通知客戶端收到了連接請求。
·第三次握手,客戶端再次向服務器端發送確認信息,確認連接。
完成三次握手,連接建立后,客戶端和服務器就可以開始進行數據傳輸了。由於這種面向連接的特性,TCP協議可以保證傳輸數據的安全,因此應用十分廣泛。
二.Java中實現TCP通信的常用方法
1.在Java中,提供了兩個類用於實現TCP通信程序
·客戶端:java.net.Socket類表示。創建Socket對象,向服務端發出連接請求,服務端響應請求,兩者建立連接開始通信。
·服務端:java.net.ServerSocket類表示。創建一個ServerSocket對象,相當於開啟一個服務,並等待客戶端的連接。
2.Socket類
Socket類:該類實現客戶端套接字。
構造方法:
·public Socket(String host,int port):使用該構造方法在創建Socket對象時,會根據參數去連接在指定地址和端口上運行的服務器程序,其中參數host接收的是一個字符串類型的IP地址。
成員方法:
·public int getPort():該方法返回一個int類型對象,該對象是Socket對象與服務器端連接的端口號。
·public InetAddress getLocalAddress():該方法用於獲取Socket對象綁定的本地IP地址,並將IP地址封裝成InetAddress類型的對象返回。
·public InputStream getInputStream():該方法返回一個InputStream類型的輸入流對象,如果該對象是由服務器的Socket返回,就用於讀取客戶端發送的數據,反之,用於讀取服務器端發送的數據。
·public OutputStream getOutputStream():該方法返回一個OutputStream類型的輸出流對象,如果該對象是由服務器的Socket返回,就用於向客戶端發送數據,反之,用於向服務器端發送數據。
·public void close():該方法用於關閉本次Socket連接,結束本次通信。
·public void shutdownOutput():禁用此套接字的輸出流。
3.ServerSocket類
ServerSocket類:該類實現了服務器套接字。
構造方法:
·public ServerSocket(int port):使用該構造方法在創建ServerSocket對象時,可以將其綁定到一個指定的端口上。端口號可以指定為0,此時系統就會分配一個還沒有被其他網絡程序所使用的端口號。
成員方法:
·public InetAddress getInetAddress():該方法用於返回一個InetAddress對象,該對象中封裝了ServerSocket綁定的IP地址。
·public Socket accept():該方法用於等待客戶端的連接,在客戶端連接之前一直處於阻塞狀態,如果有客戶端連接就返回一個與之對應的Socket對象。
·public void close():該方法用於關閉本次Socket連接,結束本次通信。
三.Java中TCP通信的過程
1.服務端:啟動,創建ServerSocket對象,等待連接。
2.客戶端:啟動,創建Socket對象,請求連接。
3.服務端:接收連接,調用accept方法,並返回一個Socket對象。
4.客戶端:Socket對象,獲取OutputStream,向服務端寫數據。
5.服務端:Socket對象,獲取InputStream,讀取客戶端發送的數據。
6.服務端:Socket對象,獲取OutputStream,向客戶端寫數據。
7.客戶端:Socket對象,獲取InputStream,解析回寫數據。
8.客戶端:釋放資源,斷開連接。
圖.服務器端和客戶端通信圖
四.代碼實現
客戶端:
服務端:
五.運行結果
客戶端與服務端能正常建立通信。
六.linux socket api
·int socket(int _domain,int _type,int _protocal):創建socket對象,此函數執行成功將返回一個打開的socket文件描述符。
·int bind(int _fd,_CONST_SOCKADDR_ARG _addr,socklen_t _len):綁定本地IP地址與端口。
·int listen(int _fd,int _n):監聽網絡,執行成功返回0,失敗返回-1。
·int connect(int _fd,_CONST_SOCKADDR_ARG _addr,socklen_t _len):客戶端發起連接。
·int accept(int _fd,_SOCKADDR_ARG _addr,socklen_t *_restrict _addr_len):服務器接收連接。
·ssize_t read(int _fd,void *_buf,size_t _nbytes):讀socket對象數據。
·ssize_t write(int _fd,_const void *_buf,sie_t _n):向socket對象寫入數據。
·ssize_t send(int _fd,_const void *_buf,sie_t _n,int _flags):發送數據。
·ssize_t recv(int _fd,_const void *_buf,sie_t _n,int _flags):接收數據。
·int close(int _fd):關閉socket對象。
·int getsockname(int _fd,_SOCKADDR_ARG _addr,socklen _t *_restrict_len):獲取socket本地及對端信息。