网易首页 > 网易号 > 正文 申请入驻

Golang网络编程net包浅析

0
分享至

新钛云服已累计为您分享665篇技术干货

最近做了一个项目,其中用到了网络编程,下面和大家分享下在Go中网络编程的实现

在Go中, 网络编程主要通过 net 包实现。支持 包括TCP/IP、UDP、域名解析和Unix域socket等连接,此外,还通过 net/http ,net/rpc 等提供了 HTTP,RPC等主流应用层的连接协议。

1、TCP 服务

TCP 是最常用的网络连接方式,以 TCP 连接为例,一个简单的 TCP 连接代码示例。

Client:


package main

import (
"bufio"
"fmt"
"os"
"strings"
"net"
)

func main() {
conn, err := net.Dial("tcp", "tyun.cn:8088")
if err != nil {
//handle
}
defer conn.Close()
inputReader := bufio.NewReader(os.Stdin)
for{
//读取输入
readString,_ :=inputReader.ReadString('\n')
trim := strings.Trim(readString,"\r\n")
_,err :=conn.Write([]byte(trim))
if err!=nil{
return
}
buf := [512]byte{}
n,err := conn.Read(buf[:])
if err!=nil{
return
}
fmt.Println(string(buf[:n]))
}

}

Server:


package main

import (
"bufio"
"fmt"
"net"
)

func main() {
listen,err:= net.Listen("tcp",":8088")
if err != nil{
//handle
}
for {
conn,err := listen.Accept()
if err != nil{
//handle
continue
}
defer conn.Close()
for {
//处理
reader := bufio.NewReader(conn)
var buf [1024]byte
read,err:= reader.Read(buf[:])
if err != nil{
//handle
}
recv := string(buf[:read])
fmt.Println("GET MESSAGE: ",recv)
conn.Write([]byte(recv))
}
}
}

2、TCP 连接在系统调用层面的实现

包括 TCP/IP 在内的各种网络连接,在类 unix 的操作系统里,都是通过网络系统调用实现的,使用系统调用创建 TCP 服务器的核心流程是:

·首先得能创建socket ,也就是得有个 create 的接口;

·其次还得能绑定 ip 和端口号,也就是 bind,不然别人找不到你;

·有了这些还得有点东西,那就是别人怎么连接你。也就是要有个 connect 和 accept 的功能;

·再者还得实现读和写,也就是 read 和 write,因为我们要通过socket 通信,不能读不能写肯定不行;

·通信完毕后socket 要关闭;

·创建 socket 连接 s = socket(AF_INET, SOCK_STREAM, 0);

·绑定 地址 bind(s, (struct sockaddr *) &serv_addr, sizeof(serv_addr));

·启动监听 listen(s,5);

·接收客户端的连接 ns= accept(s, (struct sockaddr *)&cli_addr, &clilen);

·接收数据 n = read( ns,buffer,255 );

·发送数据,n = write(ns,"hello world",11)。

创建 TCP 客 户端的核心流程:

·创建 socket 连接 s= socket(AF_INET, SOCK_STREAM, 0);

·连接服务器地址:connect(s, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

·接收数据 n = read( ns,buffer,255 );

·发送数据,n = write(ns,"hello world",11)。

socket()等系统调用的实现,是 kernel 层面完成的,而net包就是对这些底层的流程做了封装。

3、Go中TCP连接的实现

在客户端中,建立连接conn, err := net.Dial("tcp", "tyun.cn:8088")的底层源码实现方法是:

func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn, error)

这个方法解析完网络和地址后 ,主要有2种连接方式:

if len(fallbacks) > 0 {
c, err = sd.dialParallel(ctx, primaries, fallbacks)
} else {
c, err = sd.dialSerial(ctx, primaries)
}

而这两种连接方式的都是调用:

func (sd *sysDialer) dialSingle(ctx context.Context, ra Addr) (c Conn, err error)

sd.dialSingle又支持4种类型:

sd.dialTCP(ctx, la, ra)

sd.dialUDP(ctx, la, ra)

sd.dialIP(ctx, la, ra)

sd.dialUnix(ctx, la, ra)

接续往下追溯,就能看到其实调用的是socket函数,实现系统调用socket()。

如果多个 goroutine 对 conn 进行读写,就会有多重读,多重写两种情况,socket 是全双工,所以读写之间互不影响。多 goroutine 读的时候,其实没什么影响。因为读的话,不会重复读,多重读不会引发安全问题。

多 goroutine 写的时候,就有问题了。多个 goroutine 写不能每个写一半,必须保证每次写是原子操作,好在 Go内部实现写的时候加了锁。

TCP 连接建立后,每当客户端发来请求时,服务端会建立新的连接。

conn,err := listen.Accept()

这个方法同样往下追溯,能看到其实最底层的实现是系统调用syscall.Accept。

连接通信的过程中,如果某一方突然关闭,那另一方会有啥反应?在实践的过程中,总结如下:

·当对端异常关闭,如果己方 socket 中有数据,那么己方是会继续读取;当 socket 中无数据时,己方 Read 函数返回 EOF;

·当对端异常关闭,己方如果还在 socket 的缓冲中写入,那么本次写入成功,下次写入就报错;

·当己端关闭,读写均异常错误。

4、结语

以上就是关于Go网络编程的一些分享,虽然net包提供了对网络原语的访问,但大多数使用者只需要Dial、Listen和Accpet函数的基本接口;以及Conn和Listener接口。

net包主要是增加 context 控制,封装了一些不同的连接类型以及DNS 查找等等,同时在有需要的地方引入 goroutine 提高处理效率。

了解新钛云服

往期技术干货

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
4月29日俄乌最新:普京的有趣回应

4月29日俄乌最新:普京的有趣回应

西楼饮月
2026-04-29 18:22:13
俄高层摊牌了,提议恢复苏联旧制,向全国交底:必须重返战时轨道

俄高层摊牌了,提议恢复苏联旧制,向全国交底:必须重返战时轨道

潮鹿逐梦
2026-04-29 01:17:49
曝希罗与热火今夏或分手!火箭成潜在下家:可打包谢泼德伊森交易

曝希罗与热火今夏或分手!火箭成潜在下家:可打包谢泼德伊森交易

罗说NBA
2026-04-30 06:42:53
汤姆斯杯:中国队3-2击败印度,取得小组赛3连胜,头名晋级

汤姆斯杯:中国队3-2击败印度,取得小组赛3连胜,头名晋级

侧身凌空斩
2026-04-29 22:12:54
网红白冰成名史:曾是发廊小哥,一条广告66万,奢侈到无法想象

网红白冰成名史:曾是发廊小哥,一条广告66万,奢侈到无法想象

叶公子
2026-04-29 14:19:53
老公转账200,让我筹办公公寿宴,我订了三箱泡面,现场一片死寂

老公转账200,让我筹办公公寿宴,我订了三箱泡面,现场一片死寂

云端小院
2026-04-30 07:00:37
体制内“女儿国”现象越来越严重,领导吐槽:工作都不好开展!

体制内“女儿国”现象越来越严重,领导吐槽:工作都不好开展!

灯锦年
2026-04-27 14:10:17
难以置信!有福州家长深夜11点多接班主任电话,被宣读防溺水事项

难以置信!有福州家长深夜11点多接班主任电话,被宣读防溺水事项

火山詩话
2026-04-29 08:42:45
欧冠马竞1-1阿森纳暗藏隐患!连伤三大主力,西蒙尼却底气十足

欧冠马竞1-1阿森纳暗藏隐患!连伤三大主力,西蒙尼却底气十足

夜白侃球
2026-04-30 09:11:19
被中年阿姨的“生活智慧”惊到了!厨房那叫一个干净,真是了不起

被中年阿姨的“生活智慧”惊到了!厨房那叫一个干净,真是了不起

室内设计师有料儿
2026-04-24 10:29:38
国家统计局:2025年在六个主要行业就业的农民工收入均保持增长

国家统计局:2025年在六个主要行业就业的农民工收入均保持增长

界面新闻
2026-04-30 09:42:23
拜托!不要再拿“致敬”当抄袭的遮羞布

拜托!不要再拿“致敬”当抄袭的遮羞布

细雨中的呼喊
2026-04-28 15:35:07
葡超又爆冷!葡体2-2差本菲卡2分,穆帅笑了:后3场拿7分进欧冠

葡超又爆冷!葡体2-2差本菲卡2分,穆帅笑了:后3场拿7分进欧冠

体育知多少
2026-04-30 07:07:33
女子啃老10年,自尽后老母亲收拾房间发现银行卡,查看余额后崩溃

女子啃老10年,自尽后老母亲收拾房间发现银行卡,查看余额后崩溃

白云故事
2025-03-17 07:55:10
重磅消息!泰国亮出万亿底牌,誓要绕开马六甲!中泰下了一盘大棋

重磅消息!泰国亮出万亿底牌,誓要绕开马六甲!中泰下了一盘大棋

阿腩讲娱乐
2026-04-30 05:32:43
武汉鄂A老牌放号,有人从光谷打车40公里来选!

武汉鄂A老牌放号,有人从光谷打车40公里来选!

音乐时光的娱乐
2026-04-30 07:07:18
震惊!“夏雨荷”一夜之间消失,济南大明湖的地标路牌,已经抹去

震惊!“夏雨荷”一夜之间消失,济南大明湖的地标路牌,已经抹去

火山詩话
2026-04-30 06:09:31
刚刚,深圳率先发布楼市新政

刚刚,深圳率先发布楼市新政

地产大爆炸
2026-04-29 20:35:45
全球人均GDP榜单出炉:来看中、美、俄、印、日、韩等国数据吧

全球人均GDP榜单出炉:来看中、美、俄、印、日、韩等国数据吧

南生今世说
2026-04-30 00:25:04
如何让孩子拥有发达的前额叶?复旦脑科学家说,这6个方法很关键

如何让孩子拥有发达的前额叶?复旦脑科学家说,这6个方法很关键

上观新闻
2026-04-27 22:39:05
2026-04-30 10:23:00
新钛云服
新钛云服
云管理服务专家
468文章数 30关注度
往期回顾 全部

科技要闻

四巨头财报齐发:AI已经不只是风口

头条要闻

牛弹琴:特朗普自以为找到妙计对伊放话 伊朗估计气懵了

头条要闻

牛弹琴:特朗普自以为找到妙计对伊放话 伊朗估计气懵了

体育要闻

一场九球狂欢,各路神仙批量下凡

娱乐要闻

马頔一句话,孙杨妈妈怒骂节目组2小时

财经要闻

一场20年级别的供应危机,在眼前了!

汽车要闻

技术天花板再摸高 全能型的奕境X9首秀

态度原创

旅游
本地
教育
亲子
公开课

旅游要闻

光影映太行 文旅焕新彩——河北涉县“五一”主题文旅活动重磅启幕

本地新闻

用青花瓷的方式,打开西溪湿地

教育要闻

五年级数学:已知三角形面积是20、30和35,求阴影面积

亲子要闻

春季感冒发烧的孩子特别多,家长困扰

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版