Java網路程式設計之Socket

2021-08-16 15:20:40 字數 3707 閱讀 8849

網路模型

tcp協議與udp協議區別

網路程式設計的本質是兩個裝置之間的資料交換,當然,在計算機網路中,裝置主要指計算機。資料傳遞本身沒有多大的難度,不就是把乙個裝置中的資料傳送給兩外乙個裝置,然後接受另外乙個裝置反饋的資料。 現在的網路程式設計基本上都是基於請求/響應方式的,也就是乙個裝置傳送請求資料給另外乙個,然後接收另乙個裝置的反饋。在網路程式設計中,發起連線程式,也就是傳送第一次請求的程式,被稱作客戶端(client),等待其他程式連線的程式被稱作伺服器(server)。客戶端程式可以在需要的時候啟動,而伺服器為了能夠時刻相應連線,則需要一直啟動。例如以打**為例,首先撥號的人類似於客戶端,接聽**的人必須保持**暢通類似於伺服器。 連線一旦建立以後,就客戶端和伺服器端就可以進行資料傳遞了,而且兩者的身份是等價的。在一些程式中,程式既有客戶端功能也有伺服器端功能,最常見的軟體就是bt、emule這類軟體了。

在現實生活中,如果要打**則需要知道對應人的**號碼,如果要寄信則需要知道收信人的位址。在網路中也是這樣,需要知道乙個裝置的位置,則需要使用該裝置的ip位址,具體的連線過程由硬體實現,程式設計師不需要過多的關心。ip位址是乙個規定,現在使用的是ipv4,既由4個0-255之間的數字組成,在計算機內部儲存時只需要4個位元組即可。在計算機中,ip位址是分配給網絡卡的,每個網絡卡有乙個唯一的ip位址,如果乙個計算機有多個網絡卡,則該台計算機則擁有多個不同的ip位址,在同乙個網路內部,ip位址不能相同。ip位址的概念類似於**號碼、身份證這樣的概念。 由於ip位址不方便記憶,所以有專門創造了網域名稱(domain name)的概念,其實就是給ip取乙個字元的名字,例如163.com、sina.com等。ip和網域名稱之間存在一定的對應關係。如果把ip位址模擬成身份證號的話,那麼網域名稱就是你的姓名。其實在網路中只能使用ip位址進行資料傳輸,所以在傳輸以前,需要把網域名稱轉換為ip,這個由稱作dns的伺服器專門來完成。

為了在一台裝置上可以執行多個程式,人為的設計了埠(port)的概念,類似的例子是公司內部的分機號碼。規定乙個裝置有216個,也就是65536個埠,每個埠對應乙個唯一的程式。每個網路程式,無論是客戶端還是伺服器端,都對應乙個或多個特定的埠號。由於0-1024之間多被作業系統占用,所以實際程式設計時一般採用1024以後的埠號。 使用埠號,可以找到一台裝置上唯一的乙個程式。所以如果需要和某台計算機建立連線的話,只需要知道ip位址或網域名稱即可,但是如果想和該台計算機上的某個程式交換資料的話,還必須知道該程式使用的埠號。

小結

網路程式設計就是使用ip位址,或網域名稱,和埠連線到另一台計算機上對應的程式,按照規定的協議(資料格式)來交換資料,實際程式設計中建立連線和傳送、接收資料在語言級已經實現,做的更多的工作是設計協議,以及編寫生成和解析資料的**罷了,然後把資料轉換成邏輯的結構顯示或控制邏輯即可。 對於初學者,或者沒有接觸過網路程式設計的程式設計師,會覺得網路程式設計涉及的知識很高深,很難,其實這是一種誤解,當你的語法熟悉以後,其實基本的網路程式設計現在已經被實現的異常簡單了。

網路模型圖

socket就是為網路服務提供的一種機制。

通訊的兩端都有sokcet

資料在兩個sokcet間通過io傳輸。

udp: a、是面向無連線, 將資料及源的封裝成資料報中,不需要建立連線

b、每個資料報的大小限制64k內

c、因無連線,是不可靠協議

d、不需要建立連線,速度快

tcp: a、建議連線,形成傳輸資料的通道.

b、在連線中進行大資料量傳輸,以位元組流方式

c 通過三次握手完成連線,是可靠協議

d 必須建立連線效率會稍低

服務端

客戶端

在tcp/ip協議中,tcp協議採用三次握手建立乙個連線。

第一次握手:建立連線時,客戶端傳送syn包(syn=j)到伺服器,並進入syn_send狀態,等待伺服器確認; 

第二次握手:伺服器收到syn包,必須確認客戶的syn(ack=j+1),同時自己也傳送乙個syn包(syn=k),即syn+ack包,此時伺服器v狀態; 

第三次握手:客戶端收到伺服器的syn+ack包,向伺服器傳送確認包ack(ack=k+1),此包傳送完畢,客戶端和伺服器進入established狀態,完成三次握手。

完成三次握手,客戶端與伺服器開始傳送資料,

個人理解是這樣的

四次揮手

由於tcp連線是全雙工的,因此每個方向都必須單獨進行關閉。這個原則是當一方完成它的資料傳送任務後就能傳送乙個fin來終止這個方向的連線。收到乙個 fin只意味著這一方向上沒有資料流動,乙個tcp連線在收到乙個fin後仍能傳送資料。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

(1)客戶端a傳送乙個fin,用來關閉客戶a到伺服器b的資料傳送。

(2)伺服器b收到這個fin,它發回乙個ack,確認序號為收到的序號加1。和syn一樣,乙個fin將占用乙個序號。

(3)伺服器b關閉與客戶端a的連線,傳送乙個fin給客戶端a。

(4)客戶端a發回ack報文確認,並將確認序號設定為收到序號加1。

1.為什麼建立連線協議是三次握手,而關閉連線卻是四次握手呢?

這是因為服務端的listen狀態下的socket當收到syn報文的建連請求後,它可以把ack和syn(ack起應答作用,而syn起同步作用)放在 乙個報文裡來傳送。但關閉連線時,當收到對方的fin報文通知時,它僅僅表示對方沒有資料傳送給你了;但未必你所有的資料都全部傳送給對方了,所以你可以未必會馬上會關閉socket,也即你可能還需要傳送一些資料給對方之後,再傳送fin報文給對方來表示你同意現在可以關閉連線了,所以它這裡的ack報 文和fin報文多數情況下都是分開傳送的.

2.為什麼time_wait狀態還需要等2msl後才能返回到closed狀態?

這是因為雖然雙方都同意關閉連線了,而且握手的4個報文也都協調和傳送完畢,按理可以直接回到closed狀態(就好比從syn_send狀態到establish狀態那樣);但是因為我們必須要假想網路是不可靠的,你無法保證你最後傳送的ack報文會一定被對方收到,因此對方處於last_ack狀態下的socket可能會因為超時未收到ack報文,而重發fin報文,所以這個time_wait狀態的作用就是用來重發可能丟失的ack報文。

伺服器**

客戶端**

java網路程式設計之SOCKET

建立物件的時候就會建立連線 try socket socket new socket time.nist.gov 13 catch ioeception ex 可選的 socket.setsotimeout 150000 從socket中讀取資料 inputstream in socket.geti...

網路程式設計之socket

套接字 socket 是乙個抽象層,應用程式可以通過它傳送或接收資料,可對其進行像對檔案一樣的開啟 讀寫和關閉等操作。套接字允許應用程式將i o插入到網路中,並與網路中的其他應用程式進行通訊。網路套接字是ip位址與埠的組合。套接字起源於 20 世紀 70 年代加利福尼亞大學伯克利分校版本的 unix...

網路程式設計之socket

1,socket 通訊 服務端 import socket server socket.socket server.bind 127.0.0.1,8080 server.listen 5 conn,addr server.accept data conn.recv 1024 print data c...