TCP/UDP網(wǎng)絡(luò)編程通信協(xié)議

上圖中,TCP/IP協(xié)議中的四層分別是應(yīng)用層、傳輸層、網(wǎng)絡(luò)層和鏈路層,每層分別負(fù)責(zé)不同的通信功能,接下來(lái)針對(duì)這四層進(jìn)行詳細(xì)地講解。

鏈路層:鏈路層是用于定義物理傳輸通道,通常是對(duì)某些網(wǎng)絡(luò)連接設(shè)備的驅(qū)動(dòng)協(xié)議,例如針對(duì)光纖、網(wǎng)線提供的驅(qū)動(dòng)。

網(wǎng)絡(luò)層:網(wǎng)絡(luò)層是整個(gè)TCP/IP協(xié)議的核心,它主要用于將傳輸?shù)臄?shù)據(jù)進(jìn)行分組,將分組數(shù)據(jù)發(fā)送到目標(biāo)計(jì)算機(jī)或者網(wǎng)絡(luò)。

傳輸層:主要使網(wǎng)絡(luò)程序進(jìn)行通信,在進(jìn)行網(wǎng)絡(luò)通信時(shí),可以采用TCP協(xié)議,也可以采用UDP協(xié)議。

應(yīng)用層:主要負(fù)責(zé)應(yīng)用程序的協(xié)議,例如HTTP協(xié)議、FTP協(xié)議等。

1.1IP地址和端口號(hào)

要想使網(wǎng)絡(luò)中的計(jì)算機(jī)能夠進(jìn)行通信,必須為每臺(tái)計(jì)算機(jī)指定一個(gè)標(biāo)識(shí)號(hào),通過(guò)這個(gè)標(biāo)識(shí)號(hào)來(lái)指定接受數(shù)據(jù)的計(jì)算機(jī)或者發(fā)送數(shù)據(jù)的計(jì)算機(jī)。

在TCP/IP協(xié)議中,這個(gè)標(biāo)識(shí)號(hào)就是IP地址,它可以唯一標(biāo)識(shí)一臺(tái)計(jì)算機(jī),目前,IP地址廣泛使用的版本是IPv4,它是由4個(gè)字節(jié)大小的二進(jìn)制數(shù)來(lái)表示,如:00001010000000000000000000000001。由于二進(jìn)制形式表示的IP地址非常不便記憶和處理,因此通常會(huì)將IP地址寫(xiě)成十進(jìn)制的形式,每個(gè)字節(jié)用一個(gè)十進(jìn)制數(shù)字(0-255)表示,數(shù)字間用符號(hào)“.”分開(kāi),如 “192.168.1.100”。

隨著計(jì)算機(jī)網(wǎng)絡(luò)規(guī)模的不斷擴(kuò)大,對(duì)IP地址的需求也越來(lái)越多,IPV4這種用4個(gè)字節(jié)表示的IP地址面臨枯竭,因此IPv6便應(yīng)運(yùn)而生了,IPv6使用16個(gè)字節(jié)表示IP地址,它所擁有的地址容量約是IPv4的8×1028倍,達(dá)到2128個(gè)(算上全零的),這樣就解決了網(wǎng)絡(luò)地址資源數(shù)量不夠的問(wèn)題。

通過(guò)IP地址可以連接到指定計(jì)算機(jī),但如果想訪問(wèn)目標(biāo)計(jì)算機(jī)中的某個(gè)應(yīng)用程序,還需要指定端口號(hào)。在計(jì)算機(jī)中,不同的應(yīng)用程序是通過(guò)端口號(hào)區(qū)分的。端口號(hào)是用兩個(gè)字節(jié)(16位的二進(jìn)制數(shù))表示的,它的取值范圍是0~65535,其中,0~1023之間的端口號(hào)用于一些知名的網(wǎng)絡(luò)服務(wù)和應(yīng)用,用戶的普通應(yīng)用程序需要使用1024以上的端口號(hào),從而避免端口號(hào)被另外一個(gè)應(yīng)用或服務(wù)所占用。


接下來(lái)通過(guò)一個(gè)圖例來(lái)描述IP地址和端口號(hào)的作用,如下圖所示。


1.1InetAddress

public class Example01{

? ?public static void main(String[] args) throws Exception {

? ? ? InetAddress local = InetAddress.getLocalHost();

? ? ?InetAddress remote = InetAddress.getByName("www.itcast.cn");

? ? ?System.out.println("本機(jī)的IP地址:" + local.getHostAddress());

? ? ?System.out.println("itcast的IP地址:" + remote.getHostAddress());

? ? ?System.out.println("itcast的主機(jī)名為:" + remote.getHostName());

? ? }

}

TCP/UDP

UDP:(適用于即時(shí)通信(QQ聊天 對(duì)數(shù)據(jù)準(zhǔn)確性和丟包要求比較低,但速度必須快),在線視頻(RTSP 速度一定要快,保證視頻連續(xù),但是偶爾花了一個(gè)圖像幀,人們還是能接受的),網(wǎng)絡(luò)語(yǔ)音電話(VoIP 語(yǔ)音數(shù)據(jù)包一般比較小,需要高速發(fā)送,偶爾斷音或串音也沒(méi)有問(wèn)題)等等。)

1,將數(shù)據(jù)和源及目的封裝在數(shù)據(jù)包中,不需要建立連接

2,每個(gè)數(shù)據(jù)包的大小限制在64k內(nèi)

3,因無(wú)連接,是不可靠協(xié)議

4,不需要建立連接,速度快

TCP:(對(duì)準(zhǔn)確率要求較高,適用于文件傳輸。郵件發(fā)送、上傳,下載

1.建立連接,行程傳輸數(shù)據(jù)的通道

2.在連接中形成大數(shù)據(jù)量傳輸

3.通過(guò)三次握手完成連接,是可靠協(xié)議

4.必須建立連接,是可靠協(xié)議


UDP:

要實(shí)現(xiàn)UDP通信需要?jiǎng)?chuàng)建一個(gè)發(fā)送端程序和一個(gè)接收端程序,很明顯,在通信時(shí)只有接收端程序先運(yùn)行,才能避免因發(fā)送端發(fā)送的數(shù)據(jù)無(wú)法接收,而造成數(shù)據(jù)丟失。因此,首先需要來(lái)完成接收端程序的編寫(xiě)。

UDP完成數(shù)據(jù)的發(fā)送

/*

*發(fā)送端

* 1,創(chuàng)建DatagramSocket對(duì)象

* 2,創(chuàng)建DatagramPacket對(duì)象,并封裝數(shù)據(jù)

* 3,發(fā)送數(shù)據(jù)

* 4,釋放流資源

*/

public?class?UDPSend {

public?static?void?main(String[] args)throwsIOException {

//1,創(chuàng)建DatagramSocket對(duì)象

DatagramSocket sendSocket =new?DatagramSocket();

//2,創(chuàng)建DatagramPacket對(duì)象,并封裝數(shù)據(jù)

//public DatagramPacket(byte[]buf,intlength, InetAddress address,intport)

//構(gòu)造數(shù)據(jù)報(bào)包,用來(lái)將長(zhǎng)度為length的包發(fā)送到指定主機(jī)上的指定端口號(hào)。

byte[ ] buffer ="hello,UDP".getBytes();

DatagramPacket dp =new?DatagramPacket(buffer, buffer.length, InetAddress.getByName("192.168.75.58"), 12306);

//3,發(fā)送數(shù)據(jù)

//public void send(DatagramPacket p)從此套接字發(fā)送數(shù)據(jù)報(bào)包

sendSocket.send(dp);

//4,釋放流資源

sendSocket.close();

?}

}

UDP完成數(shù)據(jù)的接收

/*

* UDP接收端

*

* 1,創(chuàng)建DatagramSocket對(duì)象

* 2,創(chuàng)建DatagramPacket對(duì)象

* 3,接收數(shù)據(jù)存儲(chǔ)到DatagramPacket對(duì)象中

* 4,獲取DatagramPacket對(duì)象的內(nèi)容

* 5,釋放流資源

*/

publicclassUDPReceive {

public?static?void?main (String[]args)?throws?IOException {

//1,創(chuàng)建DatagramSocket對(duì)象,并指定端口號(hào)

DatagramSocket ?receiveSocket =?new?DatagramSocket(12306);

//2,創(chuàng)建DatagramPacket對(duì)象,創(chuàng)建一個(gè)空的倉(cāng)庫(kù)

byte[ ] buffer=new?byte[1024];

DatagramPacket dp =?new?DatagramPacket (buffer, 1024);

//3,接收數(shù)據(jù)存儲(chǔ)到DatagramPacket對(duì)象中

receiveSocket.receive(dp);

//4,獲取DatagramPacket對(duì)象的內(nèi)容

//誰(shuí)發(fā)來(lái)的數(shù)據(jù)getAddress()

InetAddress ipAddress=dp.getAddress();

String ?ip = ipAddress.getHostAddress();//獲取到了IP地址

//發(fā)來(lái)了什么數(shù)據(jù)getData()

byte[ ] data=dp.getData();

//發(fā)來(lái)了多少數(shù)據(jù)getLenth()

int ?length ?= ?dp.getLength();

//顯示收到的數(shù)據(jù)

String ?dataStr ?= ?new ?String(data,0,length);

System.out.println("IP地址:"+ip+"數(shù)據(jù)是"+dataStr);

//5,釋放流資源

receiveSocket.close();

}

}

TCP通信

要實(shí)現(xiàn)TCP通信需要?jiǎng)?chuàng)建一個(gè)服務(wù)器端程序和一個(gè)客戶端程序,為了保證數(shù)據(jù)傳輸?shù)陌踩?,首先需要?shí)現(xiàn)服務(wù)器端程序。



文件上傳案例:

目前大多數(shù)服務(wù)器都會(huì)提供文件上傳的功能,由于文件上傳需要數(shù)據(jù)的安全性和完整性,很明顯需要使用TCP協(xié)議來(lái)實(shí)現(xiàn)。接下來(lái)通過(guò)一個(gè)案例來(lái)實(shí)現(xiàn)圖片上傳的功能。如下圖所示。原圖:文件上傳.bmp



文件上傳案例多線程版本:


實(shí)現(xiàn)服務(wù)器端可以同時(shí)接收多個(gè)客戶端上傳的文件。

l我們要修改服務(wù)器端代碼



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容