Java利用TCP協議實現客戶端與服務器通信【附通信源碼】

      網友投稿 944 2022-05-29

      進行TCP協議網絡程序的編寫,關鍵在于ServerSocket套接字的熟練使用,TCP通信中所有的信息傳輸都是依托ServerSocket類的輸入輸出流進行的。

      目錄

      TCP協議概念

      ServerSocket類

      服務器端程序

      客戶端程序

      Hello!大家好哇!我是灰小猿!

      上一篇博客和大家分享了在網絡編程中要注意的基礎知識,關于IP、TCP、UDP以及端口和套接字的一些概念,想了解的小伙伴可以看我的這篇文章“盤點那些進行網絡編程必須要知道的基礎知識”,那么今天大灰狼就來和大家分享一下如何使用TCP/IP進行網絡程序的開發。

      TCP協議概念

      先來了解一下TCP協議的基本概念。

      我們知道TCP是可靠而非安全的網絡協議。它可以保證數據在從一端送至另一端的時候可以準確的送達,并且抵達的數據的排列順序和送出時的順序是相同的。因此在進行TCP協議通信的時候,我們首先應該保證客戶端和服務器之間的連接通暢。

      而TCP協議程序的編寫,仍然是依靠套接字Socket類來實現的,并且利用TCP協議進行通信的兩個程序之間是有主次之分的,即一個是服務器的程序,另一個是客戶端的程序。因此兩者的功能和編寫上也略有不同。如下圖是服務器與客戶端之間進行通信的示意圖:

      以上就是在TCP協議中客戶端與服務器建立連接的過程示意圖。而在這其中起到關鍵作用的就是服務器端套接字ServerSocket和客戶端套接字Socket。通過這兩個套接字來建立服務器和客戶端,從而利用其中的函數進行數據的通信。

      在ServerSocket類中有很多需要注意的地方,接下來大灰狼和大家分享一下ServerSocket類的具體用法:

      ServerSocket類

      ServerSocket類存在于Java.net包中,表示服務器端的套接字,在使用時需要首先導入這個類,我們也知道ServerSocket類的主要功能就是通過指定的端口等待來自于網絡中客戶端的請求并且進行連接。

      值得注意的是:服務器套接字一次只能與一個客戶端套接字進行連接,因此如果存在多臺客戶端同時發送連接請求,則服務器套接字就會將請求的客戶端存放到隊列中去,然后從中取出一個套接字與服務器建立的套接字進行連接,但是服務器端能夠容納的客戶端套接字也不是無限的,當請求連接的數量大于最大容納量時,那么多出來的請求就會被拒接,一般來說隊列的默認大小是50。

      ServerSocket類的構造方法通常會拋出IOException異常,具體有以下幾種形式:

      ServerSocket():創建非綁定服務器套接字

      ServerSocket(inr port):創建綁定到特定端口的服務器套接字

      ServerSocket(int port, int backlog):利用指定的backlog創建服務器套接字,并將其綁定到指定的服務器端口上,

      ServerSocket(int port, int backlog, InetAddress bindAddress):使用指定的端口,偵聽backlog和要綁定到本地的IP地址創建服務器。這種情況適用于計算機上有多個網卡和多個IP地址的情況,用戶可以明確的規定ServerSocket在哪塊網卡或哪個IP地址上等待用戶的連接請求。

      以下是ServerSocket類中一些常用的方法:

      方法

      了解了ServerSocket類的基本方法之后,就是如何進行客戶端和服務器進行連接的問題了。

      在服務器端我們可以調用ServerSocket類的accpet()方法與請求連接的客戶機建立連接,這時會返回一個和客戶端相連接的Socket對象,這個時候其實已經連接成功了,使用getInetAddress()方法就可以獲取到進行請求的客戶機的IP地址。

      對于如何進行客戶端和服務器端數據的通信,就要用到數據的輸入流和輸出流了,服務器端的Socket對象使用getOutputStream()方法獲取到的輸出流,將指向客戶端的Socket對象使用getInputStream()方法獲取到的輸入流。由此就實現在服務器向客戶端發送數據的一個過程,同樣的道理,客戶端端的Socket對象使用getOutputStream()方法獲取到的輸出流,將指向服務器端的Socket對象使用getInputStream()方法獲取到的輸入流。從而實現由客戶端向服務器發送數據的過程。

      注意:accpet()方法會阻塞線程的繼續執行,如果在對應的接口沒有收到客戶端的呼叫,則程序會停留在此處,直到獲取到客戶端的呼叫才會繼續向下執行,但是如果服務器沒有收到來自客戶端的呼叫請求,并且accpet()方法沒有發生阻塞,那么通常情況下就是程序出了問題,一般來說可能是使用了一個已經被其他程序占用了的端口號,導致ServerSocket沒有綁定成功!遇到這種情況可以嘗試更換新的端口號。

      了解了TCP協議的通信過程,接下來就是進行TCP通信程序的書寫啦!

      在網絡通信中,如果只要求客戶機向服務器發送信息,不要求服務器向客戶端反饋信息的行為稱為“單向通信”,要求客戶機和服務器雙方互相通信的過程稱為“雙向通信”,雙向通信只不過是比單向通信多了一個服務器向客戶端發送消息的過程,

      接下來分別是服務器端和客戶端程序的編寫:

      服務器端程序

      package server_1; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class MyTcp { private ServerSocket server; //設置服務器套接字 private Socket client; //設置客戶端套接字 //連接客戶端函數 void getServer() { try { server = new ServerSocket(1100); //建立服務器 端口為1100 System.out.println("服務器建立成功!正在等待連接......"); client = server.accept(); //調用服務器函數對客戶端進行連接 System.out.println("客戶端連接成功!ip為:" + client.getInetAddress()); //返回客戶端IP getClientMessage(); //調用信息傳輸和接收函數 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } void getClientMessage() { try { while (true) { InputStream is = client.getInputStream(); //獲取到客戶端的輸入流 byte[] b = new byte[1024]; //定義字節數組 int len = is.read(b); //由于信息的傳輸是以二進制的形式,所以要以二進制的形式進行數據的讀取 String data = new String(b, 0,len); System.out.println("客戶端發來消息:" + data); //定義發送給客戶端的輸出流 OutputStream put = client.getOutputStream(); String putText = "我已經收到!歡迎你!"; put.write(putText.getBytes()); //將輸出流信息以二進制的形式進行寫入 } } catch (Exception e) { // TODO: handle exception } try { //判斷客戶端字節流不是空,則關閉客戶端 if (server != null) { server.close(); } } catch (Exception e) { // TODO: handle exception } } public static void main(String[] args) { // TODO Auto-generated method stub MyTcp myTcp = new MyTcp(); //調用該類生成對象 myTcp.getServer(); //調用方法 } }

      客戶端程序

      package client_1; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; public class MyClient { private Socket client; //定義客戶端套接字 //建立客戶端函數 void getClient() { try { client = new Socket("127.0.0.1", 1100); //建立客戶端,使用的IP為127.0.0.1,端口和服務器一樣為1100 System.out.println("客戶端建立成功!"); setClientMessage(); //調用客戶端信息寫入函數 } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //定義客戶端信息寫入函數 void setClientMessage() { try { OutputStream pt = client.getOutputStream(); //建立客戶端信息輸出流 String printText = "服務器你好!我是客戶端!"; pt.write(printText.getBytes()); //以二進制的形式將信息進行輸出 InputStream input = client.getInputStream(); //建立客戶端信息輸入流 byte [] b = new byte[1024]; //定義字節數組 int len = input.read(b); //讀取接收的二進制信息流 String data = new String(b, 0,len); System.out.println("收到服務器消息:" + data); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { //如果客戶端信息流不為空,則說明客戶端已經建立連接,關閉客戶端 if (client != null) { client.close(); } } catch (Exception e) { // TODO: handle exception } } public static void main(String[] args) { // TODO Auto-generated method stub //生成客戶端類對象 MyClient myClient = new MyClient(); myClient.getClient(); } }

      同時要注意:在客戶端和服務器搭建成功之后,應該先打開服務器等待連接,再打開客戶端進行連接,同樣在進行關閉時,應該先關閉客戶端,再關閉服務器。

      以上面程序為例:

      打開服務器等待客戶端連接

      Java利用TCP協議實現客戶端與服務器通信【附通信源碼】

      打開客戶端與服務器連接成功,并且實現雙向通信:

      注意:當一臺機器上安裝了多個網絡應用程序時,很可能指定的端口已經被占用,甚至還可能遇到之前運行很好的程序突然卡住的情況,這種情況很可能是端口被別的程序占用了,這時可以運行netstat-help來活的幫助,可以使用命令netstat-an來查看該程序所使用的端口。

      覺得有用記得關注喲!

      大灰狼期待與你一同進步^ω^

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:評估板快速測試-基于TI Sitara Cortex-A9
      下一篇:用Python獲取知乎問題答案并轉換為MarkDown文件
      相關文章
      亚洲AV无码一区二区三区鸳鸯影院| 亚洲第一男人天堂| 国产精品亚洲精品日韩动图 | 亚洲精品国精品久久99热| 亚洲人成网站在线播放2019 | 亚洲乱码一二三四区国产| 亚洲精品欧洲精品| 亚洲第一成年人网站| 亚洲精品视频在线观看免费| 亚洲高清美女一区二区三区| 亚洲国产精品久久久久久| 亚洲AV成人精品网站在线播放| 亚洲AV无码久久精品成人| 久久精品国产96精品亚洲 | 亚洲AV无码一区二区二三区入口| 国产V亚洲V天堂A无码| 久久久久亚洲AV无码专区首| 亚洲国产成人精品不卡青青草原| 亚洲日韩图片专区第1页| 91亚洲va在线天线va天堂va国产| 亚洲视频网站在线观看| 亚洲日产2021三区| 亚洲一欧洲中文字幕在线| 亚洲成人免费在线观看| 国产精品亚洲精品| 亚洲第一第二第三第四第五第六| 精品亚洲成a人在线观看| 亚洲精品无码AV中文字幕电影网站 | 国产成人人综合亚洲欧美丁香花| 综合偷自拍亚洲乱中文字幕| 亚洲真人日本在线| 国产亚洲综合久久系列| 久久青青草原亚洲av无码app | 亚洲国产精品成人精品小说| va天堂va亚洲va影视中文字幕| 亚洲色成人WWW永久在线观看| 国产AV无码专区亚洲AV琪琪| 亚洲伊人久久精品影院| 亚洲精品视频在线| 国产成+人+综合+亚洲专| 亚洲AV无码精品国产成人|