网络通信 udp+tcp+http

本文包括udp客户端、udp服务器、tcp客户端、tcp服务器、http客户端、http服务器

net包提供了可移植的网络I/O接口,包括TCP/IP、UDP、域名解析和Unix域socket。

主要实现3个步骤:初始化+发送数据+接收数据。


udp客户端

初始化+发送数据+接收数据

package main

import (

    "os"

    "fmt"

    "net"

//  "io"

)

func main() {

    conn, err := net.Dial("udp", "127.0.0.1:11110")

    defer conn.Close()

    if err != nil {

        os.Exit(1) 

    }

    conn.Write([]byte("Hello world!")) 

    fmt.Println("send msg")

    var msg [20]byte

    conn.Read(msg[0:])

    fmt.Println("msg is", string(msg[0:10]))

}


udp服务端

初始化+监听+接收数据+发送数据

package main

import (

    "os"

    "fmt"

    "net"

)

func checkError(err error){

    if  err != nil {

        fmt.Println("Error: %s", err.Error())

        os.Exit(1) 

    }

}

func recvUDPMsg(conn *net.UDPConn){

    var buf [20]byte

    n, raddr, err := conn.ReadFromUDP(buf[0:])

    if err != nil {

        return 

    }

    fmt.Println("msg is ", string(buf[0:n]))

    //WriteToUDP

    //func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error)

    _, err = conn.WriteToUDP([]byte("nice to see u"), raddr)

    checkError(err)

}

func main() {

    udp_addr, err := net.ResolveUDPAddr("udp", ":11110")

    checkError(err)

    conn, err := net.ListenUDP("udp", udp_addr)

    defer conn.Close()

    checkError(err)

    //go recvUDPMsg(conn)

    recvUDPMsg(conn)

}


tcp客户端

初始化+发送数据+接收数据

package main

import (

    "fmt"

    "io/ioutil"

    "net"

)

func main() {

    var remoteAddress, _ = net.ResolveTCPAddr("tcp4", "127.0.0.1:8080") //生成一个net.TcpAddr对像。

    var conn, err = net.DialTCP("tcp4", nil, remoteAddress) //传入协议,本机地址(传了nil),远程地址,获取连接。

    if err != nil { //如果连接失败。则返回。

        fmt.Println("连接出错:", err)

        return

    }

    var remoteIpAddress = conn.RemoteAddr() //获取IP地址的方法。

    fmt.Println("远程IP地址是:", remoteIpAddress) //输出:220.181.111.188:80

    var localIPAddress = conn.LocalAddr()

    fmt.Println("本地IP地址是:", localIPAddress) //输出:192.168.1.9:45712


    conn.Write([]byte("hello")) //尝试发送些信息。

  fmt.Println("发送完毕: ")

    //var reciverBuffer []byte                      //定义一个空切片,用于接收结果。

    //len, err := conn.Read(reciverBuffer) //返回接收到的字节数。

   fmt.Println("等待接收: ")

    bys, err := ioutil.ReadAll(conn) //接收消息。

    if err != nil {

        fmt.Println("接收出错:", err)

    }

    //var reciveText = string(reciverBuffer[0:len])

    var reciveText = string(bys)

    fmt.Println(reciveText)

    conn.Close() //关闭连接

    fmt.Println("程序结束")

}


tcp服务器

初始化+监听tcp+接收连接+接收数据+发送数据

package main

import (

    "fmt"

    "io/ioutil"

    "net"

)


func main() {

    localAddress, _ := net.ResolveTCPAddr("tcp4", "127.0.0.1:8080") //定义一个本机IP和端口。

    var tcpListener, err = net.ListenTCP("tcp", localAddress) //在刚定义好的地址上进监听请求。

    if err != nil {

        fmt.Println("监听出错:", err)

        return

    }

    defer func() { //担心return之前忘记关闭连接,因此在defer中先约定好关它。

        tcpListener.Close()

    }()

    fmt.Println("正在等待连接...")

    var conn, err2 = tcpListener.AcceptTCP() //接受连接。

    if err2 != nil {

        fmt.Println("接受连接失败:", err2)

        return

    }

    var remoteAddr = conn.RemoteAddr() //获取连接到的对像的IP地址。

    fmt.Println("接受到一个连接:", remoteAddr)

    fmt.Println("正在读取消息...")

    var bys, _ = ioutil.ReadAll(conn) //读取对方发来的内容。

    fmt.Println("接收到客户端的消息:", string(bys))

    conn.Write([]byte("hello, Nice to meet you, my name is SongXingzhu")) //尝试发送消息。

    conn.Close() //关闭连接。

  }



http客户端

发送请求+解析返回结果

package main

import ( 

    "fmt"

    "io/ioutil"

    "log"

    "net/http"

    "net/url"

func main() { 

    //resp, _ := doGet("http://www.baidu.com") 

    //resp, _ := doPost("http://www.baidu.com", "application/json;charset=utf-8") 

    resp, _ := doPostForm("http://www.baidu.com") 

    defer resp.Body.Close() //go的特殊语法,main函数执行结束前会执行resp.Body.Close() 

    fmt.Println(resp.StatusCode) //有http的响应码输出 

    if resp.StatusCode == http.StatusOK { //如果响应码为200 

        body, err := ioutil.ReadAll(resp.Body) //把响应的body读出 

        if err != nil { //如果有异常 

            fmt.Println(err) //把异常打印 

            log.Fatal(err) //日志 

        } 

        fmt.Println(string(body)) //把响应的文本输出到console 

    } 

/** 

以GET的方式请求 

**/

func doGet(url string) (r *http.Response, e error) { 

    resp, err := http.Get(url) 

    if err != nil { 

        fmt.Println(resp.StatusCode) 

        fmt.Println(err) 

        log.Fatal(err) 

    } 

    return resp, err 

/** 

以POST的方式请求 

**/

func doPost(url string, bodyType string) (r *http.Response, e error) { 

    resp, err := http.Post(url, bodyType, nil) 

    if err != nil { 

        fmt.Println(resp.StatusCode) 

        fmt.Println(err) 

        log.Fatal(err) 

    } 

    return resp, err 

/** 

以Post表单的方式请求 

**/

func doPostForm(urlStr string) (r *http.Response, e error) { 

    v := url.Values{"method": {"get"}, "id": {"1"}} 

    v.Add("name1", "1") 

    v.Add("name2", "2") 

    resp, err := http.PostForm(urlStr, v) 

    if err != nil { 

        fmt.Println(resp.StatusCode) 

        fmt.Println(err) 

        log.Fatal(err) 

    } 

    return resp, err 

}

func httpDo() {

    client := &http.Client{}

    req, err := http.NewRequest("POST", "http://www.01happy.com/demo/accept.php", strings.NewReader("name=cjb"))

    if err != nil {

        // handle error

    }

    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

    req.Header.Set("Cookie", "name=anny")

    resp, err := client.Do(req)

    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)

    if err != nil {

        // handle error

    }

    fmt.Println(string(body))

}


发送请求+解析返回结果

package main

import (

"fmt"

"io/ioutil"

"net/http"

)

func main() {

// response, _ := http.Get("http://www.baidu.com")

// defer response.Body.Close()

// body, _ := ioutil.ReadAll(response.Body)

// fmt.Println(string(body))

client := &http.Client{}

request, _ := http.NewRequest("GET", "http://192.168.1.189:4000/bye", nil)

request.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")

request.Header.Set("Accept-Charset", "GBK,utf-8;q=0.7,*;q=0.3")

request.Header.Set("Accept-Encoding", "gzip,deflate,sdch")

request.Header.Set("Accept-Language", "zh-CN,zh;q=0.8")

request.Header.Set("Cache-Control", "max-age=0")

request.Header.Set("Connection", "keep-alive")

response, _ := client.Do(request)

if response.StatusCode == 200 {

body, _ := ioutil.ReadAll(response.Body)

bodystr := string(body)

fmt.Println(bodystr)

}

}



http服务器

注册服务+监听请求

package main

import (

    "fmt"

    "net/http"

    "reflect"

    "strings"

)

func hello(w http.ResponseWriter, req *http.Request) {

    w.Write([]byte("Hello"))

}

type Handlers struct {

}

func (h *Handlers) ResAction(w http.ResponseWriter, req *http.Request) {

    fmt.Println("res")

    w.Write([]byte("res"))

}

func say(w http.ResponseWriter, req *http.Request) {

    pathInfo := strings.Trim(req.URL.Path, "/")

    fmt.Println("pathInfo:", pathInfo)

    parts := strings.Split(pathInfo, "/")

    fmt.Println("parts:", parts)

    var action = "ResAction"

    fmt.Println(strings.Join(parts, "|"))

    if len(parts) > 1 {

        fmt.Println("22222222")

        action = strings.Title(parts[1]) + "Action"

    }

    fmt.Println("action:", action)

    handle := &Handlers{}

    controller := reflect.ValueOf(handle)

    method := controller.MethodByName(action)

    r := reflect.ValueOf(req)

    wr := reflect.ValueOf(w)

    method.Call([]reflect.Value{wr, r})

}

func main() {

    http.HandleFunc("/hello", hello)

    http.Handle("/handle/", http.HandlerFunc(say))

    http.ListenAndServe(":8001", nil)

    //select {} //阻塞进程

}



注册服务+监听请求

package main

import (

    "log"

    "net/http"

)

func main() {

    //注册一个函数,响应某一个路由

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

        w.Write([]byte("hello this is version 1!!"))

    })

    //这里可以单独写一个函数传递给当前的路由

    http.HandleFunc("/bye", SayBye)

    log.Println("Start version v1")

    log.Fatal(http.ListenAndServe(":4000", nil))

}

func SayBye(w http.ResponseWriter, r *http.Request) {

    w.Write([]byte("Bye bye, this is version v1"))

    log.Println("saybye")

    //进行一个流式传递,将字符串转换为byte类型

}


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容

  • 计算机网络七层模型中,传输层有两个重要的协议:(1)用户数据报协议UDP (User Datagram Proto...
    Q南南南Q阅读 1,714评论 0 3
  • 网络由下往上分为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。通过初步的了解,我知道IP协议对应于...
    木溪bo阅读 204评论 0 0
  • 简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者...
    保川阅读 5,956评论 1 13
  • 简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者...
    JasonShi6306421阅读 1,240评论 0 1
  • 个人认为,Goodboy1881先生的TCP /IP 协议详解学习博客系列博客是一部非常精彩的学习笔记,这虽然只是...
    贰零壹柒_fc10阅读 5,054评论 0 8