Go入門系列(十)網(wǎng)絡(luò)

目錄
一杠巡、TCP編程
二、UDP編程

其實(shí)前幾天買了本書雇寇,今天終于到貨了氢拥,滿懷欣喜的打開目錄,socket編程锨侯、數(shù)據(jù)庫嫩海、I/O統(tǒng)統(tǒng)沒有,額囚痴。叁怪。。

回歸正題深滚,關(guān)于TCP/UDP的基礎(chǔ)我們不做過多解釋了奕谭,大家可自行補(bǔ)充或可參考python網(wǎng)絡(luò)編程【python入門系列(十)】輔助理解,才不是打廣告的說痴荐。

一血柳、TCP編程

我們借助net包來模擬一個(gè)系統(tǒng),服務(wù)端可以相應(yīng)來自用戶端的輸入生兆,借助我們之前學(xué)到的并發(fā)难捌,允許它為多個(gè)用戶提供連接,且通過循環(huán)持續(xù)響應(yīng)用戶請求鸦难,在收到exit時(shí)斷開連接:

  • Server
    Server端借助net包的Listen()方法創(chuàng)建監(jiān)聽:
func Listen(network, address string) (Listener, error)
//network:選用的協(xié)議:TCP栖榨、UDP,    如:“tcp”或 “udp” 注意:只支持小寫字母
//address:IP地址+端口號,             如:“127.0.0.1:8000”或 “:8000”

數(shù)據(jù)交互時(shí)明刷,發(fā)送使用Write()方法婴栽,接收使用Read()方法。

func main() {
    listener, err := net.Listen("tcp", "127.0.0.1:8000")
    checkErr(err)
    defer listener.Close()

    for {
        conn, err := listener.Accept()
        checkErr(err)
        go task(conn)
    }
}
func task(conn net.Conn)  {
    defer conn.Close()
    addr :=  conn.RemoteAddr( ).String()
    fmt.Println(addr, " connect sucessful" )
    buf := make([ ]byte, 1024)
    for{
        n, err := conn.Read(buf)
        checkErr(err)
        if string(buf[:n])=="exit"{
            conn.Write([]byte("拜拜~~~~"))
            conn.Close()
            fmt.Println(addr, " Disconnect sucessful" )
            return
        }
        fmt.Printf("read buf = %s\n", string(buf[:n]))
        response:="Hello "+string(buf[:n])
        conn.Write([]byte(response))
    }
}

func checkErr(err error) {
    if err != nil {
        fmt.Println(err.Error())
        return
    }
}
#控制臺
127.0.0.1:54815  connect sucessful
read buf = rabbit
read buf = carrot
127.0.0.1:54815  Disconnect sucessful

我們稍加總結(jié)下最重要的數(shù)據(jù)交互規(guī)則:

func taskdemo(c net.Conn) {
    //some code...

    //Simple read from connection
    buffer := make([]byte, 1024)
    c.Read(buffer)

    //simple write to connection
    c.Write([]byte("Hello from server"))
}
  • Client
    CIient端用到的方法幾乎與server端一致辈末,創(chuàng)建服務(wù)器連接依賴net包的Dial()方法:
func Dial(network, address string) (Conn, error)
//network:選用的協(xié)議:TCP愚争、UDP映皆,如:“tcp”或 “udp”
//address:服務(wù)器IP地址+端口號, 如:“127.0.0.1:8000”或 “www.baidu.com:80”
func main() {
    conn, err := net.Dial("tcp", "127.0.0.1:8000")
    if err != nil {
        fmt.Println("連接失敗,錯(cuò)誤:", err)
        return
    }
    defer conn.Close()
    for{
        var name string
        _, _ = fmt.Scanln(&name)
        conn.Write([]byte(name))

        buf := make([]byte,1024)
        n,_ := conn.Read(buf)
        fmt.Println(string(buf[:n]))
    }

}
#控制臺
rabbit
Hello rabbit
carrot
Hello carrot
exit
拜拜~~~~

二轰枝、UDP編程

UDP連接是一個(gè)不負(fù)責(zé)任的連接,如果不允許你的消息丟包鞍陨,那記得做好接收反饋,如果沒有接收成功記得重發(fā)缭裆,但是UDP的特點(diǎn)在于它不需要持續(xù)的會(huì)話,意味著在某些場景下他更加隱匿寿烟,比如木馬澈驼、木馬、和木馬缝其。

  • Server
    UDP編程Server端借助net包的ListenUDP()方法,數(shù)據(jù)交互讀取使用ReadFromUDP()方法内边,發(fā)送使用WriteToUDP()方法,關(guān)于其并發(fā)的處理位置我們借助實(shí)例體會(huì):
func main() {
    udpAddr, _ := net.ResolveUDPAddr("udp", "127.0.0.1:8000")
    listener, err := net.ListenUDP("udp", udpAddr)
    checkErr(err)
    fmt.Println("Start listening ... ")
    defer listener.Close()
    task(listener)
}

func task(conn *net.UDPConn)  {
    defer conn.Close()
    buf := make([ ]byte, 1024)
    for{
        n, addr, err := conn.ReadFromUDP(buf)
        checkErr(err)
        fmt.Printf("read buf = %s\n", string(buf[:n]))
        go func(){
            response:="Hello "+string(buf[:n])
            conn.WriteToUDP([]byte(response),addr)
        }()
    }
}

func checkErr(err error) {
    if err != nil {
        fmt.Println(err.Error())
        return
    }
}
#控制臺
Start listening ... 
read buf = rabbit
read buf = carrot

我們將UDP的并發(fā)處理放到了閉包這里待锈,另外我們對數(shù)據(jù)交互的規(guī)則簡單整理下:

func taskdemo(c *net.UDPConn) {
    //some code...

    //simple read
    buffer := make([]byte, 1024)
    n, addr, err:= c.ReadFromUDP(buffer)

    //simple write to connection
    c.WriteToUDP([]byte("Hello from server"),addr)
}
  • Client
    如果我們偷懶假残,直接使用tcp的client是完全可以的,把tcp修改為udp:
func main() {
    conn, err := net.Dial("udp", "127.0.0.1:8000")
    if err != nil {
        fmt.Println("連接失敗炉擅,錯(cuò)誤:", err)
        return
    }
    defer conn.Close()
    for{
        var name string
        _, _ = fmt.Scanln(&name)
        conn.Write([]byte(name))

        buf := make([]byte,1024)
        n,_ := conn.Read(buf)
        fmt.Println(string(buf[:n]))
    }
}
#控制臺
rabbit
Hello rabbit
carrot
Hello carrot

當(dāng)然谍失,像服務(wù)端一樣,使用ReadFromUDP()方法和WriteToUDP()方法也是可以的快鱼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末纲岭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子止潮,更是在濱河造成了極大的恐慌,老刑警劉巖喇闸,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異唆樊,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嘿辟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門片效,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人堤舒,你說我怎么就攤上這事∩噻停” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵陵吸,是天一觀的道長。 經(jīng)常有香客問我壮虫,道長,這世上最難降的妖魔是什么囚似? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任线得,我火速辦了婚禮,結(jié)果婚禮上募狂,老公的妹妹穿的比我還像新娘。我一直安慰自己祸穷,他們只是感情好勺三,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吗坚,像睡著了一般胯舷。 火紅的嫁衣襯著肌膚如雪绊含。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天逃顶,我揣著相機(jī)與錄音充甚,去河邊找鬼。 笑死伴找,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抖誉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼袒炉,長吁一口氣:“原來是場噩夢啊……” “哼樊零!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起夺艰,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤沉衣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后厢蒜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烹植,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年巷屿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了墩虹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片憨琳。...
    茶點(diǎn)故事閱讀 38,654評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡旬昭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出问拘,到底是詐尸還是另有隱情,我是刑警寧澤绪杏,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布纽绍,位于F島的核電站,受9級特大地震影響拌夏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜辖佣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一卷谈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧世蔗,春花似錦、人聲如沸污淋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赁豆。三九已至,卻和暖如春魔种,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工属韧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蛤吓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓柱衔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哲戚。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容