[笔记] Golang Socket

loveyx · · 2293 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

1. Socket 简介

常用的 Socket 类型有两种:流式 Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。

流式是一种面向连接的 Socket,针对于面向连接的 TCP 服务应用;

数据报式 Socket 是一种无连接的 Socket,对应于无连接的 UDP 服务应用

2. 网络中的进程之间如何通过 Socket 通信呢?

网络层的“ip 地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。这样利用
三元组(ip 地址,协议,端口)就可以标识网络的进程了,网络中需要互相通信的进程,就可以利用这个标志在他们之间进行交互。

3. 代码示例:客户端模拟HTTP 协议

 1 package main
 2 
 3 import (
 4     "fmt"
 5     "io/ioutil"
 6     "net"
 7     "os"
 8 )
 9 
10 func main() {
11     service := "www.baidu.com:80"
12     // tcpAddr, 将域名+端口,解析成 ip+端口
13     tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
14     fmt.Println(tcpAddr)
15     checkError(err)
16     conn, err := net.DialTCP("tcp", nil, tcpAddr)
17     checkError(err)
18     _, err = conn.Write([]byte("HEAD / HTTP/1.0\r\n\r\n"))
19     checkError(err)
20     result, err := ioutil.ReadAll(conn)
21     checkError(err)
22     fmt.Println(string(result))
23 }
24 
25 func checkError(err error) {
26     if err != nil {
27         fmt.Fprintf(os.Stderr, "Fatal error:%s", err.Error())
28     }
29 }
View Code

4. 代码示例:TCP,客户端与服务器交互

/server/main.go

 1 package main
 2 
 3 import (
 4     "fmt"
 5     "net"
 6     "os"
 7     "time"
 8 )
 9 
10 func main() {
11     listener, err := net.Listen("tcp", "localhost:2300")
12     checkError(err)
13     fmt.Println("Service Starting...")
14     defer listener.Close()
15     for {
16         conn, err := listener.Accept()
17         fmt.Println("已连接:", conn.LocalAddr())
18         if err != nil {
19             continue
20         }
21         go handleClient(conn)
22     }
23 }
24 
25 func checkError(err error) {
26     if err != nil {
27         fmt.Fprintf(os.Stderr, "Fatal error:%s", err.Error())
28     }
29 }
30 
31 func handleClient(conn net.Conn) {
32     defer conn.Close()
33     daytime := time.Now().String()
34     conn.Write([]byte(daytime))
35 
36 }
View Code

 /client/main.go

 1 package main
 2 
 3 import (
 4     "fmt"
 5     "net"
 6     "os"
 7 )
 8 
 9 func main() {
10     conn, err := net.Dial("tcp", "localhost:2300")
11     checkError(err)
12     bt := make([]byte, 1024)
13     _, err = conn.Read(bt)
14     fmt.Println(string(bt))
15     defer conn.Close()
16 }
17 
18 func checkError(err error) {
19     if err != nil {
20         fmt.Fprintf(os.Stderr, "Fatal error:%s", err.Error())
21     }
22 }
View Code

 5. 代码示例:UDP,客户端与服务器交互

/server/main.go

 1 package main
 2 
 3 import (
 4     "fmt"
 5     "net"
 6     "os"
 7     "time"
 8 )
 9 
10 func main() {
11     service := "localhost:1200"
12     udpAddr, err := net.ResolveUDPAddr("udp", service)
13     conn, err := net.ListenUDP("udp", udpAddr)
14     checkError(err)
15     fmt.Println("Starting...")
16     for {
17         handleClient(conn)
18     }
19 }
20 
21 func checkError(err error) {
22     if err != nil {
23         fmt.Fprintf(os.Stderr, "Fatal error ", err.Error())
24         os.Exit(1)
25     }
26 }
27 
28 func handleClient(conn *net.UDPConn) {
29     fmt.Println("接收到请求了,开始处理")
30     var buf [512]byte
31     _, addr, err := conn.ReadFromUDP(buf[0:])
32     if err != nil {
33         return
34     }
35     fmt.Println(string(buf[0:]))
36     daytime := time.Now().String()
37     conn.WriteToUDP([]byte(daytime), addr)
38 }
View Code

/client/main.go

 1 package main
 2 
 3 import (
 4     "fmt"
 5     "net"
 6     "os"
 7 )
 8 
 9 func main() {
10     service := "localhost:1200"
11     udpAddr, err := net.ResolveUDPAddr("udp", service)
12     checkError(err)
13     conn, err := net.DialUDP("udp", nil, udpAddr)
14     checkError(err)
15     conn.Write([]byte("hello world"))
16     var bt [512]byte
17     conn.ReadFromUDP(bt[0:])
18     fmt.Println(string(bt[0:]))
19     defer conn.Close()
20 }
21 
22 func checkError(err error) {
23     if err != nil {
24         fmt.Fprintf(os.Stderr, "Fatal error ", err.Error())
25         os.Exit(1)
26     }
27 }
View Code

 


有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:loveyx

查看原文:[笔记] Golang Socket

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2293 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传