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  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)
    }
}
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 本文通過回顧 teleport (https://github.com/henrylee2cn/teleport)...
    Andeya閱讀 8,686評論 4 14
  • 從三月份找實習到現在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發崗...
    時芥藍閱讀 42,367評論 11 349
  • 原文地址:http://www.cnblogs.com/skynet/archive/2010/12/12/190...
    archyly閱讀 1,073評論 0 8
  • 寫著玩…… 自起名墨,一撮黑土,不是黃土、白沙,更不是巖石,來于自然,生命盡頭歸于自然,希望有點營養、有點文化、有...
    小墨022T閱讀 200評論 0 0
  • 醒來甚覺愛你。 想了一夜的你, 枕邊無你。 夢了一下午的你, 醒后無你。 是清晨的空虛 是傍晚的茫然 原諒我早晨的...
    一只夏妖閱讀 166評論 0 0