Golang的socket编程(一):常用数据结构和函数介绍

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

工作的原因接触到socket,要使用socket实现一个长连接。之前只在C/C++上用过socket,而且在学校的时候也只是简单的做聊天室小程序,并没有涉及到长连接。突然用到工作项目上,心里还是有点悬的,毕竟网上的资料也不是很多。这里就一步一步记录下学习的过程、遇到的问题以及最重要的——解决问题的方法。

一、说明

golang中的socket需要用到net包,里面封装好了很多常用的函数方法以及元素类型。而且无需像C一样要经历socket,bind,listen,accept等等流程,只需要简单的几步流程就能完成,非常方便。

二、IP类型

net包中定义的ip类型直接就是byte数组:

1
type IP []byte

我们可以使用func parseIP(s string) IP 来把一个ip地址转换成IP类型:

1
2
3
4
5
6
7
ipAddr := "192.168.1.79"
addr := net.ParseIP(ipAddr)
if addr == nil{
fmt.Println("unavaliable addr")
}else{
fmt.Println(addr.To16())
}

三、函数

3.1 funcResolveTCPAddr(net, addr string) (*TCPAddr, error)

ResolveTCPAddr 函数的功能是解析TCP连接的地址,包含ipport

  • nettcp tcp4 tcp6三选一,分别表示TCPv4,TCPv6和任意,默认是tcp4
  • addr:主机的地址,可以是[ip+port],也可以是[domain+port],可以省略主机部分,表示本机地址

返回一个*TCPAddr 类型 ,表示一个TCP连接地址:

1
2
3
4
5
type TCPAddr struct {
IP IP
Port int
Zone string // IPv6 scoped addressing zone
}

3.2 func ResolveIPAddr(net, addr string) (*IPAddr, error)

ResolveIPAddr 函数的功能是解析ip地址:

  • netip ip4 ip6 分别代表IPv4,IPv6以及任意。默认留空表示ip4
  • addr :IP地址 返回一个*IPAddr 结构:
1
2
3
4
type IPAddr struct {
IP IP
Zone string // IPv6 scoped addressing zone
}

3.3 func Dial(network, address string) (Conn, error)

Dial 函数的功能是建立一个连接:

  • network: 如果是TCP连接,对应tcp tcp4 tcp6;如果是IP连接,对应ip ip4 ip6。对于ip连接,需要在后面加一个冒号然后注明协议号或者协议名字
  • address:连接的地址,ip+portdomain+port 形式,也可以省略主机地址表示本地地址217.0.0.1
    返回一个net.Conn 接口对象,包含了连接的信息,我们可以使用该对象的Write()Read() 对连接进行读写。
1
2
3
4
5
6
7
8
9
10
type Conn interface {
Read(b []byte) (n int, err error)
Write(b []byte) (n int, err error)
Close() error
LocalAddr() Addr
RemoteAddr() Addr
SetDeadline(t time.Time) error
SetReadDeadline(t time.Time) error
SetWriteDeadline(t time.Time) error
}

与这个函数相对应的两个函数:

  • func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error)
  • func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error)

分别表示建立TCP请求和IP请求,中间多的laddr 表示本地的地址,一般为nil

3.4 func (c *conn) Write(b []byte) (int, error)

conn 连接对象中写入数据,即发送数据给对方,写入的数据是[]byte 类型,成功将返回发送的数据包字节数。

1
2
3
4
5
n, err := tcpCoon.Write([]byte("HelloWorld"))
if err != nil{
fmt.Println(err)
return
}

3.5 func (c *conn) Read(b []byte) (int, error)

从conn连接对象中读取数据,成功将返回读取到的字节数。

1
2
3
4
5
6
7
recvData := make([]byte, 2048)
n, err = tcpCoon.Read(recvData)
if err != nil{
fmt.Println(err)
return
}
fmt.Println(string(recvData))

3.6 func Listen(net, laddr string) (Listener, error)

Listen函数在服务端使用,让服务端开始监听。

  • net :和上面一样,可以是tcp ip相关的值
  • laddr :要监听的地址,ip+port省略主机地址将使用本机地址127.0.0.1

相应的两个函数:

  • func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error):监听TCP连接
  • func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error):监听IP连接

3.7 func (l *TCPListener) Accept() (Conn, error)

服务端开始监听需要使用Accept 函数来接受客户端连接,此时服务端将进入阻塞状态。

相应的还有一个

  • func (l *TCPListener) AcceptTCP() (*TCPConn, error)

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

本文来自:马谦的博客

感谢作者:马谦的博客

查看原文:Golang的socket编程(一):常用数据结构和函数介绍

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

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