go Socket编程

TCP

Socket客户端

获取连接

//1.
tcpAddr, err := net.ResolveTCPAddr("tcp4", ":8080")
checkError(err)
conn, err := net.DialTCP("tcp", nil, tcpAddr)
//2.
addr := "wwww.baidu.com:80" //定义主机名
conn,err := net.Dial("tcp",addr) //拨号操作,需要指定协议。

串行指定读取客户端返回内容大小

package main
import (
    "io"
    "fmt"
    "log"
    "net"
    "reflect"
)
func main() {
    addr := "wwww.baidu.com:80" //定义主机名
    conn,err := net.Dial("tcp",addr) //拨号操作,需要指定协议。
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("访问公网IP地址是:",conn.RemoteAddr().String()) /*获取“conn”中的公网地址。注意:最好是加上后面的String方法,因为他们的那些是不一样的哟·当然你打印的时候
        可以不加输出结果是一样的,但是你的内心是不一样的哟!*/
    fmt.Printf("客户端链接的地址及端口是:%v\n",conn.LocalAddr()) //获取到本地的访问地址和端口。
    fmt.Println("“conn.LocalAddr()”所对应的数据类型是:",reflect.TypeOf(conn.LocalAddr()))
    fmt.Println("“conn.RemoteAddr().String()”所对应的数据类型是:",reflect.TypeOf(conn.RemoteAddr().String()))
    n,err := conn.Write([]byte("GET / HTTP/1.1\r\n\r\n")) //向服务端发送数据。用n接受返回的数据大小,用err接受错误信息。
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("向服务端发送的数据大小是:",n)

    buf := make([]byte,1024) //定义一个切片的长度是1024。

    n,err = conn.Read(buf) //接收到的内容大小。

    if err != nil && err != io.EOF {  //io.EOF在网络编程中表示对端把链接关闭了。
        log.Fatal(err)
    }
    fmt.Println(string(buf[:n])) //将接受的内容都读取出来。
    conn.Close()  //断开TCP链接。
}

按照指定方式循环读取

package main
import (
    "io"
    "fmt"
    "log"
    "net"
    "reflect"
)
func main() {
    addr := "wwww.baidu.com:80" //定义主机名
    conn,err := net.Dial("tcp",addr) //拨号操作,需要指定协议。
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(conn.RemoteAddr().String()) //最好是加上后面的String方法,因为他们的那些是不一样的哟·当然你打印的时候可以不加。
    fmt.Println(conn.LocalAddr())
    fmt.Println(reflect.TypeOf(conn.LocalAddr()))
    fmt.Println(reflect.TypeOf(conn.RemoteAddr().String()))
    n,err := conn.Write([]byte("GET / HTTP/1.1\r\n\r\n")) //向服务端发送数据。用n接受返回的数据大小,用err接受错误信息。
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("写入的大小是:",n)

    buf := make([]byte,10) //定义一个切片的长度是1024。

    for  {
        n,err = conn.Read(buf) //接收到的内容大小。
        if err == io.EOF {
            conn.Close()
        }
        fmt.Print(string(buf[:n]))
    }
    fmt.Println(string(buf[:n])) //将接受的内容都读取出来。
}

按行读取

package main
import (
    "io"
    "fmt"
    "log"
    "net"
    "reflect"
    "bufio"
)
func main() {
    addr := "wwww.baidu.com:80" //定义主机名
    conn,err := net.Dial("tcp",addr) //拨号操作,需要指定协议。
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(conn.RemoteAddr().String()) //最好是加上后面的String方法,因为他们的那些是不一样的哟·当然你打印的时候可以不加。
    fmt.Println(conn.LocalAddr())
    fmt.Println(reflect.TypeOf(conn.LocalAddr()))
    fmt.Println(reflect.TypeOf(conn.RemoteAddr().String()))
    n,err := conn.Write([]byte("GET / HTTP/1.1\r\n\r\n")) //向服务端发送数据。用n接受返回的数据大小,用err接受错误信息。
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("写入的大小是:",n)

    r := bufio.NewReader(conn) //将这个链接(connection)包装以下。将conn的内容都放入r中,但是没有进行读取,让步我们一会对其进行操作。
    for  {
        line,err := r.ReadString('\n') //将r的内容也就是conn的数据按照换行符进行读取。
        if err == io.EOF {
            conn.Close()
        }
        fmt.Print(line)
    }
}

io读取

package main
import (
    "io"
    "fmt"
    "log"
    "net"
    "reflect"
    "os"
)
func main() {
    addr := "wwww.baidu.com:80" //定义主机名
    conn,err := net.Dial("tcp",addr) //拨号操作,需要指定协议。
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("访问公网IP地址以及端口是:",conn.RemoteAddr().String()) /*获取“conn”中的公网地址。注意:最好是加上后面的String方法,因为他们的那些是不一样的哟·当然你打印的时候
        可以不加输出结果是一样的,但是你的内心是不一样的哟!*/
    fmt.Printf("客户端链接的地址及端口是:%v\n",conn.LocalAddr()) //获取到本地的访问地址和端口。
    fmt.Println("“conn.LocalAddr()”所对应的数据类型是:",reflect.TypeOf(conn.LocalAddr()))
    fmt.Println("“conn.RemoteAddr().String()”所对应的数据类型是:",reflect.TypeOf(conn.RemoteAddr().String()))
    n,err := conn.Write([]byte("GET / HTTP/1.1\r\n\r\n")) //向服务端发送数据。用n接受返回的数据大小,用err接受错误信息。
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("写入的大小是:",n)
    io.Copy(os.Stdout,conn)
    conn.Close()
}

Socket服务端

串行服务端

package main
import (
    "log"
    "net"
    "time"
)
func main() {
    addr := "0.0.0.0:8080" //表示监听本地所有ip的8080端口,也可以这样写:addr := ":8080"
    listener,err := net.Listen("tcp",addr) //使用协议是tcp,监听的地址是addr
    if err != nil {
        log.Fatal(err)
    }
    defer listener.Close() //关闭监听的端口
    for  {
        conn,err := listener.Accept() //用conn接收链接
        if err != nil {
            log.Fatal(err)
        }
        conn.Write([]byte("helloword\n"))  //通过conn的wirte方法将这些数据返回给客户端。
        conn.Write([]byte("hello Golang\n"))
        conn.Close() //与客户端断开连接。
    }
}

并发服务端

package main

import (
    "net"
    "log"
    "time"
)

func Handle_conn(conn net.Conn) { //这个是在处理客户端会阻塞的代码。
    conn.Write([]byte(time.Now().Local().String()))//通过conn的wirte方法将这些数据返回给客户端。
    conn.Close() //与客户端断开连接。
}
func main() {
    addr := "0.0.0.0:8080" //表示监听本地所有ip的8080端口,也可以这样写:addr := ":8080"
    listener,err := net.Listen("tcp",addr)
    if err != nil {
        log.Fatal(err)
    }
    defer listener.Close()

    for  {
        conn,err := listener.Accept() //用conn接收链接
        if err != nil {
            log.Fatal(err)
        }
        go Handle_conn(conn)  //开启多个协程。
    }
}

web并发服务器;

package main

import (
    "net"
    "log"
)

var content = `HTTP/1.1 200 OK
        Date: Sat, 29 Jul 2017 06:18:23 GMT
        Content-Type: text/html
        Connection: Keep-Alive
        Server: BWS/1.1
        X-UA-Compatible: IE=Edge,chrome=1
        BDPAGETYPE: 3
        Set-Cookie: BDSVRTM=0; path=/

<!doctype html>
<html class="no-js">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Amaze UI Admin 404 Examples</title>
  <meta name="description" content="这是一个404页面">
  <meta name="keywords" content="404">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="renderer" content="webkit">
  <meta http-equiv="Cache-Control" content="no-siteapp" />
  <meta name="apple-mobile-web-app-title" content="Amaze UI" />
  <link rel="stylesheet" href="assets/css/amazeui.min.css"/>
  <link rel="stylesheet" href="assets/css/admin.css">
</head>
<body>
<!--[if lte IE 9]>
<p class="browsehappy">你正在使用<strong>过时</strong>的浏览器,Amaze UI 暂不支持。 请 <a href="http://browsehappy.com/" target="_blank">升级浏览器</a>
  以获得更好的体验!</p>
<![endif]-->
<div >
  <!-- sidebar start -->
  <!-- sidebar end -->

  <!-- content start -->
  <div >
    <div class="admin-content-body">
      <hr>

      <div class="am-g">
        <div class="am-u-sm-12">
          <h2 class="am-text-center am-text-xxxl am-margin-top-lg">404. Not Found</h2>
          <p class="am-text-center">没有找到你要的页面</p>
</div>
</div>
</div>
<!-- content end -->

</div>
<!--[if lt IE 9]>
<script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdn.staticfile.org/modernizr/2.8.3/modernizr.js"></script>
<script src="assets/js/amazeui.ie8polyfill.min.js"></script>
<![endif]-->

<!--[if (gte IE 9)|!(IE)]><!-->

</body>
</html>`

func Handle_conn(conn net.Conn) { //这个是在处理客户端会阻塞。
    conn.Write([]byte(content)) //将html的代码返回给客户端,这样客户端在web上访问就可以拿到指定字符。
    conn.Close()
}


func main() {
    addr := "0.0.0.0:8080" //表示监听本地所有ip的8080端口,也可以这样写:addr := ":8080"
    listener,err := net.Listen("tcp",addr)
    if err != nil {
        log.Fatal(err)
    }
    defer listener.Close()

    for  {
        conn,err := listener.Accept() //用conn接收链接
        if err != nil {
            log.Fatal(err)
        }
        go Handle_conn(conn) //将接受来的链接交给该函数去处理。
    }
}

UDP

客户端

package main

import (
    "fmt"
    "net"
    "os"
)

func main() {
    if len(os.Args) != 2 {
        fmt.Fprintf(os.Stderr, "Usage: %s host:port", os.Args[0])
        os.Exit(1)
    }
    service := os.Args[1]
    udpAddr, err := net.ResolveUDPAddr("udp4", service)
    checkError(err)
    conn, err := net.DialUDP("udp", nil, udpAddr)
    checkError(err)
    _, err = conn.Write([]byte("anything"))
    checkError(err)
    var buf [512]byte
    n, err := conn.Read(buf[0:])
    checkError(err)
    fmt.Println(string(buf[0:n]))
    os.Exit(0)
}
func checkError(err os.Error) {
    if err != nil {
        fmt.Fprintf(os.Stderr, "Fatal error ", err.String())
        os.Exit(1)
    }
}

服务器

package main

import (
    "fmt"
    "net"
    "os"
    "time"
)

func main() {
    service := ":1200"
    udpAddr, err := net.ResolveUDPAddr("udp4", service)
    checkError(err)
    conn, err := net.ListenUDP("udp", udpAddr)
    checkError(err)
    for {
        handleClient(conn)
    }
}
func handleClient(conn *net.UDPConn) {
    var buf [512]byte
    _, addr, err := conn.ReadFromUDP(buf[0:])
    if err != nil {
        return
    }
    daytime := time.LocalTime().String()
    conn.WriteToUDP([]byte(daytime), addr)
}
func checkError(err os.Error) {
    if err != nil {
        fmt.Fprintf(os.Stderr, "Fatal error ", err.String())
        os.Exit(1)
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • 本文通过回顾 teleport (https://github.com/henrylee2cn/teleport)...
    Andeya阅读 8,563评论 4 14
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,183评论 11 349
  • 原文地址:http://www.cnblogs.com/skynet/archive/2010/12/12/190...
    archyly阅读 1,057评论 0 8
  • 写着玩…… 自起名墨,一撮黑土,不是黄土、白沙,更不是岩石,来于自然,生命尽头归于自然,希望有点营养、有点文化、有...
    小墨022T阅读 181评论 0 0
  • 醒来甚觉爱你。 想了一夜的你, 枕边无你。 梦了一下午的你, 醒后无你。 是清晨的空虚 是傍晚的茫然 原谅我早晨的...
    一只夏妖阅读 146评论 0 0