三次握手:
目前成都创新互联公司已为超过千家的企业提供了网站建设、域名、网页空间、绵阳服务器托管、企业网站设计、磁县网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
1. 主动发起连接请求端(客户端),发送 SYN 标志位,携带数据包、包号
2. 被动接收连接请求端(服务器),接收 SYN,回复 ACK,携带应答序列号。同时,发送SYN标志位,携带数据包、包号
3. 主动发起连接请求端(客户端),接收SYN 标志位,回复 ACK。
被动端(服务器)接收 ACK —— 标志着 三次握手建立完成( Accept()/Dial() 返回 )
四次挥手:
1. 主动请求断开连接端(客户端), 发送 FIN标志,携带数据包
2. 被动接受断开连接端(服务器), 发送 ACK标志,携带应答序列号。 —— 半关闭完成。
3. 被动接受断开连接端(服务器), 发送 FIN标志,携带数据包
4. 主动请求断开连接端(客户端), 发送 最后一个 ACK标志,携带应答序列号。—— 发送完成,客户端不会直接退出,等 2MSL时长。
等 2MSL待目的:确保服务器 收到最后一个ACK
滑动窗口:
通知对端本地存储数据的 缓冲区容量。—— write 函数在对端 缓冲区满时,有可能阻塞。
TCP状态转换:
1. 主动发起连接请求端:
CLOSED —— 发送SYN —— SYN_SENT(了解) —— 接收ACK、SYN,回发 ACK —— ESTABLISHED (数据通信)
2. 主动关闭连接请求端:
ESTABLISHED —— 发送FIN —— FIN_WAIT_1 —— 接收ACK —— FIN_WAIT_2 (半关闭、主动端)
—— 接收FIN、回复ACK —— TIME_WAIT (主动端) —— 等 2MSL 时长 —— CLOSED
3. 被动建立连接请求端:
CLOSED —— LISTEN —— 接收SYN、发送ACK、SYN —— SYN_RCVD —— 接收 ACK —— ESTABLISHED (数据通信)
4. 被动断开连接请求端:
ESTABLISHED —— 接收 FIN、发送 ACK —— CLOSE_WAIT —— 发送 FIN —— LAST_ACK —— 接收ACK —— CLOSED
windows下查看TCP状态转换:
netstat -an | findstr 端口号
Linux下查看TCP状态转换:
netstat -an | grep 端口号
TCP和UDP对比:
TCP: 面向连接的可靠的数据包传递。 针对不稳定的 网络层,完全弥补。ACK
UDP:无连接不可靠的报文传输。 针对不稳定的 网络层,完全不弥补。还原网络真实状态。
优点 缺点
TCP: 可靠、顺序、稳定 系统资源消耗大,程序实现繁复、速度慢
UDP:系统资源消耗小,程序实现简单、速度快 不可靠、无序、不稳定
使用场景:
TCP:大文件、可靠数据传输。 对数据的 稳定性、准确性、一致性要求较高的场合。
UDP:应用于对数据时效性要求较高的场合。 网络直播、电话会议、视频直播、网络游戏。
UDP-CS-Server实现流程:
1. 创建 udp地址结构 ResolveUDPAddr(“协议”, “IP:port”) —— udpAddr 本质 struct{IP、port}
2. 创建用于 数据通信的 socket ListenUDP(“协议”, udpAddr ) —— udpConn (socket)
3. 从客户端读取数据,获取对端的地址 udpConn.ReadFromUDP() —— 返回:n,clientAddr, err
4. 发送数据包给 客户端 udpConn.WriteToUDP("数据", clientAddr)
UDP-CS-Client实现流程:
1. 创建用于通信的 socket。 net.Dial("udp", "服务器IP:port") —— udpConn (socket)
2. 以后流程参见 TCP客户端实现源码。
UDPserver默认就支持并发!
------------------------------------
命令行参数: 在main函数启动时,向整个程序传参。 【重点】
语法: go run xxx.go argv1 argv2 argv3 argv4 。。。
xxx.exe: 第 0 个参数。
argv1 :第 1 个参数。
argv2 :第 2 个参数。
argv3 :第 3 个参数。
argv4 :第 4 个参数。
使用: list := os.Args 提取所有命令行参数。
获取文件属性函数:
os.stat(文件访问绝对路径) —— fileInfo 接口
fileInfo 包含 两个接口。
Name() 获取文件名。 不带访问路径
Size() 获取文件大小。
网络文件传输 —— 发送端(客户端)
1. 获取命令行参数,得到文件名(带路径)filePath list := os.Args
2. 使用 os.stat() 获取 文件名(不带路径)fileName
3. 创建 用于数据传输的 socket net.Dial("tcp", “服务器IP+port”) —— conn
4. 发送文件名(不带路径) 给接收端, conn.write()
5. 读取 接收端回发“ok”,判断无误。封装函数 sendFile(filePath, conn) 发送文件内容
6. 实现 sendFile(filePath, conn)
1) 只读打开文件 os.Open(filePath)
for {
2) 从文件中读数据 f.Read(buf)
3) 将读到的数据写到socket中 conn.write(buf[:n])
4)判断读取文件的 结尾。 io.EOF. 跳出循环
}
网络文件传输 —— 接收端(服务器)
1. 创建用于监听的 socket net.Listen() —— listener
2. 借助listener 创建用于 通信的 socket listener.Accpet() —— conn
3. 读取 conn.read() 发送端的 文件名, 保存至本地。
4. 回发 “ok”应答 发送端。
5. 封装函数,接收文件内容 recvFile(文件路径)
1) f = os.Create(带有路径的文件名)
for {
2)从 socket中读取发送端发送的 文件内容 。 conn.read(buf)
3) 将读到的数据 保存至本地文件 f.Write(buf[:n])
4) 判断 读取conn 结束, 代表文件传输完成。 n == 0 break
}
1、学习曲线
它包含了类C语法、GC内置和工程工具。这一点非常重要,因为Go语言容易学习,所以一个普通的大学生花一个星期就能写出来可以上手的、高性能的应用。在国内大家都追求快,这也是为什么国内Go流行的原因之一。
2、效率
Go拥有接近C的运行效率和接近PHP的开发效率,这就很有利的支撑了上面大家追求快速的需求。
3、出身名门、血统纯正
之所以说Go语言出身名门,是因为我们知道Go语言出自Google公司,这个公司在业界的知名度和实力自然不用多说。Google公司聚集了一批牛人,在各种编程语言称雄争霸的局面下推出新的编程语言,自然有它的战略考虑。而且从Go语言的发展态势来看,Google对它这个新的宠儿还是很看重的,Go自然有一个良好的发展前途。我们看看Go语言的主要创造者,血统纯正这点就可见端倪了。
4、组合的思想、无侵入式的接口
Go语言可以说是开发效率和运行效率二者的完美融合,天生的并发编程支持。Go语言支持当前所有的编程范式,包括过程式编程、面向对象编程以及函数式编程。
5、强大的标准库
这包括互联网应用、系统编程和网络编程。Go里面的标准库基本上已经是非常稳定,特别是我这里提到的三个,网络层、系统层的库非常实用。
6、部署方便
我相信这一点是很多人选择Go的最大理由,因为部署太方便,所以现在也有很多人用Go开发运维程序。
7、简单的并发
它包含降低心智的并发和简易的数据同步,我觉得这是Go最大的特色。之所以写正确的并发、容错和可扩展的程序如此之难,是因为我们用了错误的工具和错误的抽象,Go可以说这一块做的相当简单。
8、稳定性
Go拥有强大的编译检查、严格的编码规范和完整的软件生命周期工具,具有很强的稳定性,稳定压倒一切。那么为什么Go相比于其他程序会更稳定呢?这是因为Go提供了软件生命周期的各个环节的工具,如go
tool、gofmt、go test。
1、服务器编程:以前你如果使用C或者C++做的那些事情,用Go来做很合适,例如处理日志、数据打包、虚拟机处理、文件系统等。
2、分布式系统、数据库代理器、中间件:例如Etcd。
3、网络编程:这一块目前应用最广,包括Web应用、API应用、下载应用,而且Go内置的net/http包基本上把我们平常用到的网络功能都实现了。
4、开发云平台:目前国外很多云平台在采用Go开发,我们所熟知的七牛云、华为云等等都有使用Go进行开发并且开源的成型的产品。
5、区块链:目前有一种说法,技术从业人员把Go语言称作为区块链行业的开发语言。如果大家学习区块链技术的话,就会发现现在有很多很多的区块链的系统和应用都是采用Go进行开发的,比如ehtereum是目前知名度最大的公链,再比如fabric是目前最知名的联盟链,两者都有go语言的版本,且go-ehtereum还是以太坊官方推荐的版本。
自1.0版发布以来,go语言引起了众多开发者的关注,并得到了广泛的应用。go语言简单、高效、并发的特点吸引了许多传统的语言开发人员,其数量也在不断增加。
使用 Go 语言开发的开源项目非常多。早期的 Go 语言开源项目只是通过 Go 语言与传统项目进行C语言库绑定实现,例如 Qt、Sqlite 等。
后期的很多项目都使用 Go 语言进行重新原生实现,这个过程相对于其他语言要简单一些,这也促成了大量使用 Go 语言原生开发项目的出现。
golang中默认以文件夹名作为包名,导入的文件的路径为$GOPATH/src
例如我们在 $GOPATH/src下面建立一个gopackage的一个文件夹,下面建立一个abc.go的文件,文件内容如下
则我们在包外部使用gopackage包中的函数时,导入格式是这样的:
我们在abc.go文件中需要导出的函数的首字母都是大写的,这是因为 只有首字母大写的标识符才可以导出 ,mutiply(int,int)int函数不可以被导出,编译失败。
当我们使用多个自定义包时如果发生冲突,怎么办呢,我们可以给不同的包提供不同的别名
如果abc.go文件中包名不是文件夹的名字,如
则在外部导入是,golang会自动为该包提供别名