第一次握手:建立連線時,客戶端傳送syn包(syn=j)到伺服器,並進入syn_sent狀態,等待伺服器確認;syn:同步序列編號(synchronize sequence numbers)。
第二次握手:伺服器收到syn包,必須確認客戶的syn(ack=j+1),同時自己也傳送乙個syn包(syn=k),即syn+ack包,此時伺服器進入syn_recv狀態;
第三次握手:客戶端收到伺服器的syn+ack包,向伺服器傳送確認包ack(ack=k+1),此包傳送完畢,客戶端和伺服器進入established(tcp連線成功)狀態,完成三次握手。
完成三次握手,客戶端與伺服器開始傳送資料,在上述過程中,還有一些重要的概念:
未連線佇列
在三次握手協議中,伺服器維護乙個未連線佇列,該隊列為每個客戶端的syn包(syn=j)開設乙個條目,該條目表明伺服器已收到syn包,並向客戶發出確認,正在等待客戶的確認包。這些條目所標識的連線在伺服器處於syn_recv狀態,當伺服器收到客戶的確認包時,刪除該條目,伺服器進入established狀態。
對於乙個已經建立的連線,tcp使用改進的三次握手來釋放連線(使用乙個帶有fin附加標記的報文段)。tcp關閉連線的步驟如下:
第一步,當主機a的應用程式通知tcp資料已經傳送完畢時,tcp向主機b傳送乙個帶有fin附加標記的報文段(fin表示英文finish)。
第二步,主機b收到這個fin報文段之後,並不立即用fin報文段回覆主機a,而是先向主機a傳送乙個確認序號ack,同時通知自己相應的應用程式:對方要求關閉連線(先傳送ack的目的是為了防止在這段時間內,對方重傳fin報文段)。
第三步,主機b的應用程式告訴tcp:我要徹底的關閉連線,tcp向主機a送乙個fin報文段。
第四步,主機a收到這個fin報文段後,向主機b傳送乙個ack表示連線徹底釋放。
由於tcp連線時全雙工的,因此,每個方向都必須要單獨進行關閉,這一原則是當一方完成資料傳送任務後,傳送乙個fin來終止這一方向的連線,
收到乙個fin只是意味著這一方向上沒有資料流動了,即不會再收到資料了,但是在這個tcp連線上仍然能夠傳送資料,直到這一方向也傳送了fin。
首先進行關閉的一方將執行主動關閉,而另一方則執行被動關閉,上圖描述的即是如此。
(1)第一次揮手:client傳送乙個fin,用來關閉client到server的資料傳送,client進入fin_wait_1狀態。
(2)第二次揮手:server收到fin後,傳送乙個ack給client,確認序號為收到序號+1(與syn相同,乙個fin占用乙個序號),server進入close_wait狀態。
(3)第三次揮手:server傳送乙個fin,用來關閉server到client的資料傳送,server進入last_ack狀態。
(4)第四次揮手:client收到fin後,client進入time_wait狀態,接著傳送乙個ack給server,確認序號為收到序號+1,server進入closed狀態,完成四次揮手。
服務端
import socket
phone = socket.socket(socket.af_inet,socket.sock_stream)#買手機
phone.setsockopt(socket.sol_socket,socket.so_reuseaddr,1) #可以多次啟動
#執行多次的時候會報錯,那麼怎麼辦呢、?就在綁卡前面加上上面那句setsockopt方法就ok了
phone.bind(('192.168.20.44',8080))#繫結手機卡(ip,埠)
# 埠號在1024以前的是系統用的,1024以後的都是你自己寫的程式去定義的埠
print('starting run......')
phone.listen(5) #開機 5代表的是最多掛起5個,也可以好多個
while true: #鏈結迴圈
coon,client_addr=phone.accept()#等待接**,(coon是建立的鏈結,客戶端的ip和埠號組成的元組)
print(coon,client_addr)
#收發訊息
while true: #通訊迴圈
try: #如果不加try...except ,就會報錯,因為它不知道你什麼時候斷開鏈結的,伺服器還以為你在執行
data = coon.recv(1024) #收了1024個位元組的訊息
print('client data 收到訊息:%s'%data.decode('utf-8'))
coon.send(data.upper()) #發訊息
except exception: #因為你不知道客戶端什麼時候斷開鏈結,
break
coon.close() #掛**
phone.close() #關機
# 處理邏輯錯誤的兩種方式:
# if 判斷
# try...except 異常處理
# 異常處理
# 當你知道直接錯誤的條件時就用if判斷了
# 當程式錯誤一定發生,但是你又預知不了它出錯的條件是什麼的時候,就用try...except
服務端
網路程式設計總結
一 確認網路環境3g wifi 1.新增原始檔和framework 1.1.新增原始檔 在你的程式中使用 reachability 只須將該例程中的 reachability.h 和 reachability.m 拷貝到你的工程中。如下圖 1.2.新增framework 將systemconfigu...
網路程式設計總結
osi分為物理層 資料鏈路層 網路層 傳輸層 會話層 表現層 應用層共七層。1.物理層 通過媒介傳輸位元,確定機械和電氣規範。位元bit 2.資料鏈路層 將位元組裝成幀和點對點的傳遞。幀frame 3.網路層 負責資料報從源到宿的傳遞和網際互聯。包packet 4.傳輸層 提供端對端的可靠的報文傳遞...
網路程式設計總結
serversocket 埠號 例項化需要填寫埠號。public serversocket int port throws ioexceptionsocket ip位址,埠號 需要填寫訪問的ip位址和埠號。socket.getoutputstream 返回socket的輸出流。socket.geti...