日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Go语言简单的TCP编程

發布時間:2025/3/21 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go语言简单的TCP编程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前期準備


  • 需要import "net"包
  • IP類型,其中一個重要的方法是IP.ParseIP(ipaddr string)來判斷是否是合法的IP地址

TCP Client


  • func (c *TCPConn) Write(b []byte) (n int, err os.Error)用于發送數據,返回發送的數據長度或者返回錯誤,是TCPConn的方法
  • func (c *TCPConn) Read(b []byte) (n int, err os.Error)用于接收數據,返回接收的長度或者返回錯誤,是TCPConn的方法
  • TCPAddr類型,保存TCP的地址信息,包括地址和端口

    type TCPAddr struct {IP IPPort int}
  • func ResolveTCPAddr(net, addr string) (*TCPAddr, os.Error)獲取一個TCPAddr,參數都是string類型,net是個const string,包括tcp4,tcp6,tcp一般使用tcp,兼容v4和v6,addr表示ip地址,包括端口號,如www.google.com:80之類的
  • func DialTCP(net string, laddr, raddr *TCPAddr) (c *TCPConn, err os.Error)用來連接(connect)到遠程服務器上,net表示協議方式,tcp,tcp4或者tcp6,laddr表示本機地址,一般為nil,raddr表示遠程地址,這里的laddr和raddr都是TCPAddr類型的,一般是上一個函數的返回值。
  • 作為一個TCP的客戶端,基本的操作流程如下:

    service="www.google.com:80"tcpAddr, err := net.ResolveTCPAddr("tcp4", service)conn, err := net.DialTCP("tcp", nil, tcpAddr)_, err = conn.Write([]byte("HEAD / HTTP/1.0\r\n\r\n"))_, err = conn.Read(b) / result, err := ioutil.ReadAll(conn)

TCP Server


  • func ListenTCP(net string, laddr *TCPAddr) (l *TCPListener, err os.Error)用來監聽端口,net表示協議類型,laddr表示本機地址,是TCPAddr類型,注意,此處的laddr包括端口,返回一個*TCPListener類型或者錯誤
  • func (l *TCPListener) Accept() (c Conn, err os.Error)用來返回一個新的連接,進行后續操作,這是TCPListener的方法,一般TCPListener從上一個函數返回得來。
  • 服務器的基本操作流程為:

    service:=":9090"tcpAddr, err := net.ResolveTCPAddr("tcp4", service)l,err := net.ListenTCP("tcp",tcpAddr)conn,err := l.Accept()go Handler(conn) //此處使用go關鍵字新建線程處理連接,實現并發

一個例子


需求


實現一個公共聊天服務器。

  • 服務器接收客戶端的信息
  • 接收完以后將客戶端的信息發送到所有的客戶端上
  • 客戶端使用/quit退出聊天
  • 只使用一套代碼,通過命令行參數啟動服務器還是客戶端

實現:
[cpp] view plain copy
  • package?main??
  • ??
  • import(??
  • ????"fmt"??
  • ????"os"??
  • ????"net"??
  • )??
  • ??
  • ??
  • //??
  • //錯誤檢查??
  • //??
  • ??
  • func?checkError(err?error,info?string)?(res?bool)?{??
  • ??????
  • ????if(err?!=?nil){??
  • ????????fmt.Println(info+"??"?+?err.Error())??
  • ????????return?false??
  • ????}??
  • ????return?true??
  • }??
  • ??
  • ??
  • //??
  • //服務器端接收數據線程??
  • //參數:??
  • //??????數據連接?conn??
  • //??????通訊通道?messages??
  • //??
  • ??
  • func?Handler(conn?net.Conn,messages?chan?string){??
  • ??????
  • ????fmt.Println("connection?is?connected?from?...",conn.RemoteAddr().String())??
  • ??????
  • ????buf?:=?make([]byte,1024)??
  • ????for{??
  • ????????lenght,?err?:=?conn.Read(buf)??
  • ????????if(checkError(err,"Connection")==false){??
  • ????????????conn.Close()??
  • ????????????break??
  • ????????}??
  • ????????if?lenght?>?0{??
  • ????????????buf[lenght]=0??
  • ????????}??
  • ????????//fmt.Println("Rec[",conn.RemoteAddr().String(),"]?Say?:"?,string(buf[0:lenght]))??
  • ????????reciveStr?:=string(buf[0:lenght])??
  • ????????messages?<-?reciveStr??
  • ??????????????
  • ????}??
  • ??????????
  • }??
  • ??
  • ??
  • //??
  • //服務器發送數據的線程??
  • //??
  • //參數??
  • //??????連接字典?conns??
  • //??????數據通道?messages??
  • //??
  • ??
  • func?echoHandler(conns?*map[string]net.Conn,messages?chan?string){??
  • ??????
  • ??????
  • ????for{??
  • ????????msg:=?<-?messages??
  • ????????fmt.Println(msg)??
  • ??????????
  • ????????for?key,value?:=?range?*conns?{??
  • ??????????????
  • ????????????fmt.Println("connection?is?connected?from?...",key)??
  • ????????????_,err?:=value.Write([]byte(msg))??
  • ????????????if(err?!=?nil){??
  • ????????????????fmt.Println(err.Error())??
  • ????????????????delete(*conns,key)??
  • ????????????}??
  • ??????????????
  • ????????}??
  • ????}??
  • ??????
  • }??
  • ??
  • ??
  • ??
  • //??
  • //啟動服務器??
  • //參數??
  • //??端口?port??
  • //??
  • ??
  • func?StartServer(port?string){??
  • ????????service:=":"+port?//strconv.Itoa(port);??
  • ????????tcpAddr,?err?:=?net.ResolveTCPAddr("tcp4",?service)??
  • ????????checkError(err,"ResolveTCPAddr")??
  • ????????l,err?:=?net.ListenTCP("tcp",tcpAddr)??
  • ????????checkError(err,"ListenTCP")??
  • ????????conns:=make(map[string]net.Conn)??
  • ????????messages?:=?make(chan?string,10)??
  • ????????//啟動服務器廣播線程??
  • ????????go?echoHandler(&conns,messages)??
  • ??????????
  • ????????for??{??
  • ????????????fmt.Println("Listening?...")??
  • ????????????conn,err?:=?l.Accept()??
  • ????????????checkError(err,"Accept")??
  • ????????????fmt.Println("Accepting?...")??
  • ????????????conns[conn.RemoteAddr().String()]=conn??
  • ????????????//啟動一個新線程??
  • ????????????go?Handler(conn,messages)???
  • ??????????????
  • ????????}??
  • ??????????
  • }??
  • ??
  • ??
  • ??
  • //??
  • //客戶端發送線程??
  • //參數??
  • //??????發送連接?conn??
  • //??
  • ??
  • func?chatSend(conn?net.Conn){??
  • ??????
  • ????var?input?string??
  • ????username?:=?conn.LocalAddr().String()??
  • ????for?{??
  • ??????????
  • ????????fmt.Scanln(&input)??
  • ????????if?input?==?"/quit"{??
  • ????????????fmt.Println("ByeBye..")??
  • ????????????conn.Close()??
  • ????????????os.Exit(0);??
  • ????????}??
  • ??????????
  • ??????????
  • ????????lens,err?:=conn.Write([]byte(username?+?"?Say?:::"?+?input))??
  • ????????fmt.Println(lens)??
  • ????????if(err?!=?nil){??
  • ????????????fmt.Println(err.Error())??
  • ????????????conn.Close()??
  • ????????????break??
  • ????????}??
  • ??????????
  • ????}??
  • ??????
  • }??
  • ??
  • ??
  • //??
  • //客戶端啟動函數??
  • //參數??
  • //??????遠程ip地址和端口?tcpaddr??
  • //??
  • ??
  • func?StartClient(tcpaddr?string){??
  • ??????
  • ????tcpAddr,?err?:=?net.ResolveTCPAddr("tcp4",?tcpaddr)??
  • ????checkError(err,"ResolveTCPAddr")??
  • ????conn,?err?:=?net.DialTCP("tcp",?nil,?tcpAddr)??
  • ????checkError(err,"DialTCP")??
  • ????//啟動客戶端發送線程??
  • ????go?chatSend(conn)?????
  • ??????
  • ????//開始客戶端輪訓??
  • ????buf?:=?make([]byte,1024)??
  • ????for{??
  • ??????????
  • ????????lenght,?err?:=?conn.Read(buf)??
  • ????????if(checkError(err,"Connection")==false){??
  • ????????????conn.Close()??
  • ????????????fmt.Println("Server?is?dead?...ByeBye")??
  • ????????????os.Exit(0)??
  • ????????}??
  • ????????fmt.Println(string(buf[0:lenght]))??
  • ??????????
  • ????}??
  • }??
  • ??
  • ??
  • ??
  • //??
  • //主程序??
  • //??
  • //參數說明:??
  • //??啟動服務器端:??Chat?server?[port]?????????????eg:?Chat?server?9090??
  • //??啟動客戶端:????Chat?client?[Server?Ip?Addr]:[Server?Port]????eg:?Chat?client?192.168.0.74:9090??
  • //??
  • ??
  • func?main(){??
  • ??????
  • ??????
  • ????if?len(os.Args)!=3??{?????
  • ????????fmt.Println("Wrong?pare")??
  • ????????os.Exit(0)??
  • ????}??
  • ??????
  • ????if?os.Args[1]=="server"?&&?len(os.Args)==3?{??
  • ??????????
  • ????????StartServer(os.Args[2])??
  • ????}??
  • ??????
  • ??????
  • ????if?os.Args[1]=="client"?&&?len(os.Args)==3?{??
  • ??????????
  • ????????StartClient(os.Args[2])??
  • ????}??
  • ??????
  • ??????
  • }??

  • 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的Go语言简单的TCP编程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。