網絡程式設計有三個要素,分别是IP位址、端口号和通信協定,那本文主要講述的是TCP與UDP這兩種通信協定,以及程式設計的實作。
首先,我們需要了解一下IP位址、端口号、通信協定的相關知識。
一、IP位址
網絡中的計算機使用IP位址來進行唯一辨別,IP位址有IPv4和IPv6兩種類型。IPv4采用十進制或二進制表示形式,十進制是一種比較常用的表示形式,如192.168.1.131,IPv6采用十六進制表示形式,一般不常用。
如何檢視IP位址相關資訊:
在Windows系統下,打開cmd,輸入指令ipconfig,按回車即可檢視。在Linux或Mac系統下,打開終端,使用ifconfig指令,按回車即可檢視。
二、端口号
端口号是計算機中的應用程式的一個整數數字标号,用來區分不同的應用程式。
0 ~ 1024 為被系統使用或保留的端口号,0 ~ 65535為有效的端口号,也就是說我們要對一些程式定義端口号的時候,要選擇1024 ~ 65535範圍内的整數數字。
比如,以前學過的MySQL的端口号是3306,SQLServer的端口号是1433,查了一下Oracle的端口号是1521。
一定要把這些資料庫對應的端口号,藏在深深的腦海裡,以後在連接配接資料庫的時候,會使用到端口号。
三、通信協定
說的通俗一點,通信協定就是網絡通信中的規則,分為TCP協定和UDP協定兩種。
第一種:TCP協定
英文名:Transmission Control Protocol 中文名:傳輸控制協定 協定說明:TCP是一種面向連接配接的、可靠的、基于位元組流的傳輸層通信協定。
舉例:打電話,需要雙方都接通,才能進行對話
特點:效率低,資料傳輸比較安全
第二種:UDP協定
英文名:User Datagram Protocol 中文名:資料報協定 協定說明:UDP是一種面向無連接配接的傳輸層通信協定。
舉例:發短信,不需要雙方建立連接配接,But,資料報的大小應限制在64k以内
特點:效率高,資料傳輸不安全,容易丢包
四、三要素關系圖與網絡模型圖
1、網絡程式設計三要素關系圖

注:圖中端口号、IP位址為示範,并非真實
2、OSI參考模型與TCP/IP參考模型
五、TCP程式設計
TCP是基于位元組流的傳輸層通信協定,是以TCP程式設計是基于IO流程式設計。
對于用戶端,我們需要使用Socket類來建立對象。對于伺服器端,我們需要使用ServerSocket來建立對象,通過對象調用accept()方法來進行監聽是否有用戶端通路。
用戶端與伺服器端圖解:
用戶端與伺服器端實作步驟:
前提:建立一個項目,在項目中建立兩個子產品(model),一個子產品用來放用戶端相關代碼,一個子產品用來放伺服器端相關代碼。
目錄結構如下圖
用戶端:
1、建立Socket對象,并指定伺服器端應用程式的端口号和伺服器端主機的IP位址。
2、使用Socket的對象調用getOutputStream()方法來擷取位元組輸出流對象。
3、調用位元組輸出流的write(byte[] buf)或者write(int b)向伺服器發送指定資料。
4、記得關閉流。
伺服器端:
1、建立ServerSocket對象,并指定該應用程式的端口号,端口号必須和用戶端指定的端口号一樣。
2、使用ServerSocket對象的accept()方法來監聽用戶端發送過來的請求,傳回值為Socket對象。
3、調用Socket對象的getInputStream()方法擷取位元組輸入流對象
4、調用位元組輸入流對象的read(byte[] buf)或read()方法擷取資料。
5、記得關閉流。
執行個體:
用戶端向伺服器端發送資訊,并顯示在伺服器端。
Client類(用戶端)
package cn.tkrnet.client;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException {
//建立Socket對象,指定要發送到伺服器端的IP位址,以及伺服器端應用程式接收的端口号
//localhost代表本機IP位址
Socket client = new Socket("localhost",9000);
//擷取輸出流,用于向伺服器端發送資料
OutputStream os = client.getOutputStream();
os.write("Java is my friend !".getBytes());
System.out.println("資訊已發送");
//關閉流
os.close();
client.close();
}
}
Server類(伺服器端)
package cn.tkrnet.server;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
System.out.println("--伺服器端已開啟--");
//建立ServerSocket對象,這裡的端口号必須與用戶端的端口号相同
ServerSocket server = new ServerSocket(9000);
//調用方法accept(),用來監聽用戶端發來的請求
Socket socket = server.accept();
//擷取輸入流對象
InputStream is = socket.getInputStream();
//讀取輸入流中的資料
int b = 0;
while ((b =is.read()) != -1){
System.out.print((char)b);
}
//關閉流
is.close();
socket.close();
server.close();
}
}
提示:在運作程式時,一定要先運作伺服器端的程式代碼,再運作用戶端的程式代碼。因為用戶端要向伺服器發送請求,前提是伺服器端要處于開啟狀态。
Server類(伺服器端)運作結果:
--伺服器端已開啟--
Client類(用戶端)運作結果:
資訊已發送
Client類(用戶端)運作後,Server類(伺服器端)收到資訊,運作結果:
Java is my friend !
1
執行個體分析:
伺服器端啟動後,伺服器端的accept()方法一直處于監聽狀态,直到用戶端連接配接了伺服器,伺服器端再從流中讀取用戶端發來的資料。
恕我直言,這是一個超級無敵簡單的單向通信執行個體。
六、UDP程式設計
UDP使用資料報進行資料傳輸,沒有用戶端與伺服器端之分,隻有發送方與接收方,兩者哪個先啟動都不會報錯,但是會出現資料丢包現象。發送的内容有字數限制,大小必須限制在64k以内。
發送方與接收方實作步驟:
前提:建立一個項目,在項目中建立兩個子產品(model),一個子產品用來放發送方相關代碼,一個子產品用來放接收方相關代碼。
發送方:
1、建立DatagramSocket對象,可以指定應用程式的端口号,也可以不指定。
2、準備需要發送的資料
3、建立DatagramPacket對象,用來對發送的資料進行打包,需要指定發送内容、發送多少、發送到哪裡和接收方的端口号四個參數。
4、調用DatagramSocket對象的send()方法發送資料。
接收方:
1、建立DatagramSocket對象,指定接收方的端口号,這個必須指定。
2、建立一個byte類型數組,用來接收發送方發送過來的資料。
3、建立DatagramPacket對象,準備接收資料。
4、調用DatagramSocket對象的receive()方法用于接收資料。
5、使用String類的構造方法将byte類型的數組中的資料轉化成String類型并顯示。
6、記得關閉流。
發送方發送資訊,接收方接收資訊,并顯示。
Sender類(發送方)
package cn.tkrnet.Sender;
import java.io.IOException;
import java.net.*;
public class Sender {
public static void main(String[] args) throws IOException {
//建立接受或發送的資料報套接字,并指定發送方的端口号為7770
DatagramSocket ds = new DatagramSocket(7770); //端口号也可以不指定
System.out.println("---發送方---");
//建立資料報對象,用來發送資料
byte[] b = "Java is my friend !".getBytes();
//8800為接收方的端口号,netAddress.getByName("localhost")是擷取主機的IP位址
DatagramPacket dp = new DatagramPacket(b,b.length, InetAddress.getByName("localhost"),7788);
ds.send(dp); //發送資料報
System.out.println("資料已發送");
//關閉流
ds.close();
}
}
Receiver類(接收方)
package cn.tkrnet.receiver;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Receiver {
public static void main(String[] args) throws IOException {
System.out.println("---接收方---");
//建立資料報套接字對象,指定的端口号要和發送方發送資料的端口号相同
// (不是發送方的端口号7770,是發送方發送資料的端口号7788)
DatagramSocket ds = new DatagramSocket(7788);
//建立接收資料報的對象
byte[] b = new byte[1024];
DatagramPacket dp = new DatagramPacket(b,b.length);
//接收資料
ds.receive(dp);
System.out.println(new String(b,0,dp.getLength()));
//關閉流
ds.close();
}
}
提示:在運作程式時,先運作發送方程式,還是先運作接收方程式都不會報錯,但是有可能會出現資料丢包,一般我們都先運作接收方的程式代碼,再運作發送方的程式代碼。
Receiver類(接收方)運作結果:
---接收方---
Sender類(發送方)運作結果:
---發送方---
資料已發送
Sender類(發送方)運作後,Receiver類(接收方)接收到資訊,運作結果:
---接收方---
Java is my friend !
隻有接收方先啟動運作,才會存在端口号為7788的程式,發送方才能發送資料到指定端口号7788,接收方才能接收資料。
不瞞你說,這也是個超級無敵簡單的單向通信執行個體。
七、總結
以上是我分享給大家的關于網絡通信TCP協定與UDP協定的一些總結。
如果覺得還不錯的話,就點個贊和在看吧!
原文連結:
https://blog.csdn.net/m0_47890251/article/details/107121432版權聲明:本文為CSDN部落客「酷酷的猿」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。