<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
基於net
包的小應用
完整程式碼已經上傳到github
GitHub-TCP
歡迎star
和issue
TCP 連線建立,三次握手
傳輸控制塊TCB:儲存了每一個連線中的一些重要資訊。比如TCP連線表,指向傳送和接收緩衝的指標,指向重傳佇列的指標,當前的傳送和接收序列等等。
假設主機A是TCP客戶程式,B是TCP伺服器程式。最初兩端的TCP程序都是處於CLOSED關閉狀態,使用者端A開啟連結,伺服器端被開啟連結。一開始B的TCP伺服器程序先建立傳輸控制塊TCB,準備接受客戶程序的連結請求,然後伺服器程序就處於LISTEN
收聽狀態,等待A的連線請求。
SYN=1
,同時選擇一個初始序號seq=x
。TCP規定,SYN報文段
(即SYN=1
的報文段)不能寫資料,但要消耗掉一個序號。這時候A就進入了同步已傳送的狀態。SYN
位和AVK
位置都置為1
,確認號為ack+1
,同時也為自己選擇一個初始序號y。同樣的這個報文段也是不能寫資料的,但同時要消耗掉一個序號。這時B進入了同步收到狀態。ACK
置1,確認號ack=y+1
,而自己的seq=x+1
。ACK報文段是可以攜帶資料的,但如果不攜帶資料則不消耗序號,在這種情況下,下一個資料包文段的序號仍為seq=x+1
。這時候TCP已經建立了。A進行入了已經建立連線的階段狀態。B收到確認後也進入了連線狀態。
TCP 連線釋放,四次揮手
資料傳輸完畢之後,通訊的雙方都可釋放連線。現在A和B都處於ESTABLISHED
狀態。
FIN
置為1
,其序號為seq=u
,它等於前面以傳送過的資料的最後一個位元組的序號加1
.這時候A進入了FIN-WAIT-1(終止等待1)
狀態,等待B的確認。注意:TCP規定,FIN報文段即使不攜帶資料,他也消耗掉一個序號!!
ack = u + 1
,而這個報文段自己的序號是v
,等於B前面已傳送過的資料的最後一個位元組的序號加1
.然後B就進入CLOSE-WAIT(關閉等待)
狀態。TCP伺服器程序這時應通知高層應用程序,因而從A到B這個方向的連結就釋放了,這時的TCP連結處於半關閉狀態,即A已經沒有資料要傳送了,但B若傳送資料,A仍要接收,也就是說,從B到A這個方向的連線並未關閉。這個狀態可能要維持一段時間。FIN-WAIT-2(終止等待2)
狀態滿等待B發出的連線釋放報文段。若B已經沒有要向A傳送的資料,其應用程序就通知TCP釋放連線,這時B發出的連線釋放報文段必須使FIN = 1
,現假定B的序號為w
(在半關閉狀態B可能又傳送了一些資料)。B還必須重複上次已傳送過的確認號ack = u + 1
.這時B就進入LAST-ACK(最後確認)
狀態,等待A的確認。ACK置1
,確認號ack=w+1
,而自己的序號是seq=u+1
(根據TCP標準,前面傳送過的FIN報文段要消耗一個序號)。然後進入到TIME-WAIT
(時間等待)狀態。注意: 現在TCP連線還沒有還沒有釋放掉
。必須經過時間等待計時器設定的時間2MSL
後,A才能進入CLOSED狀態。時間MSL叫做最長報文段壽命,RFC793建議設在兩分鐘。但是在現在工程來看兩分鐘太長了,所以TCP允許不同的實現可以根據具體情況使用更小的MSL值。
首先建立兩個目錄,一個是client
使用者端,另一個是server
伺服器端。
net
中提供了Listen
方法,可以讓伺服器端進行埠監聽
ADDRESS := "127.0.0.1:5000" listener,err := net.Listen("tcp",ADDRESS) if err != nil { fmt.Printf("start tcp server %s failed ,err : %s ",listener,err) return } defer listener.Close()
net
中提供了Dail
方法,讓使用者端連線伺服器端
ADDRESS := "127.0.0.1:5000" conn,err := net.Dial("tcp",ADDRESS) // 主動與伺服器端建立連線 if err != nil { fmt.Printf("dial %s failed; err :%s",ADDRESS,err) return }
可以通過.Read
來讀取傳輸的資料。
var data [1024]byte var msg string reader := bufio.NewReader(os.Stdin) for { // 伺服器端要時刻等待傳送過來的資料,所以要用for迴圈 //接受資訊 n,err := conn.Read(data[:]) if err == io.EOF{ break } if err != nil { fmt.Printf("read from conn failed,err:%s",err) return } fmt.Println("Access Info : ",string(data[:n])) } defer conn.Close()
同樣可以通過.Write
在傳輸連線中傳輸資料。
for{ // 讓客戶的能一直傳送資訊,所以就需要一個for迴圈,保持連線 fmt.Print("請輸入:") msg,_ = reader.ReadString('n') msg = strings.TrimSpace(msg) if msg == "exit" { break } _, _ = conn.Write([]byte(msg)) }
當伺服器端收到資訊之後,應該返回資訊給使用者端。表示已經收到了資料。
伺服器端回覆資訊
//回覆資訊 fmt.Print("回覆資訊:") msg,_ = reader.ReadString('n') msg = strings.TrimSpace(msg) if msg == "exit" { break } _ ,_ = conn.Write([]byte(msg))
使用者端收到資訊
// 接受資訊 n,err:=conn.Read(data[:]) if err == io.EOF { break } if err != nil { fmt.Println("read from conn failed, err :",err) return } fmt.Println("收到的回覆:",string(data[:n]))
以上就是Go語言TCP從原理到程式碼實現詳解的詳細內容,更多關於Go TCP原理程式碼的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45