这是我参加「第三届青训营-后端场」笔记创作活动的第2篇笔记。
socket
socket是网络编程中的王者,掌握socket就能清晰的理解服务器的运作原理,企业常用的各种中间件比如消息队列,服务器比如nginx,缓存redis等等其实现都离不开socket
socket的核心功能是实现两台主机上的两个进程之间的通信,当然单台主机上的两个进程也可以通过socket完成通信。就好像A给B打电话一样,两者要通信首先就需要各自有一个唯一的电话号码,对于socket通信而言也是如此。
主机A的地址就是ip1:port1,主机B的地址就是ip2:port2,如果主机A希望连接上主机B就存在两种方式,也就是说socket的底层实现有两种方式,一种是基于TCP,另外一种是基于UDP。
在web开发中一般存在两个角色,一个是服务端,一个是客户端,假设服务器上有一个后端程序Ser可以对外提供接口信息,其占用的端口是9090,那么也就意味着此时的Ser正在监听本机的9090端口,实时接收来自外部的请求,也就是说服务端是在监听本机的端口,就像一个前台一样,他也不知道谁要进入这个大楼,但是他知道要进入这个大楼就必须要经过自己面前的这道门,他的职责就是时时刻刻关注着,看看谁进入这道门。
在go中监听一个端口的代码为:
net.Listen("tcp",""localhost:9090")
//tcp表示传输层协议
//localhost:9090表示监听本机的9090端口
而对于客户端而言,他的第一目的是连接到远程的服务端,那么他就需要对远端发起请求,也就是找到大楼的位置并走进去。
在go当中请求连接到一个端口的代码为:
net.Dial("tcp",""localhost:9090")
//tcp表示传输层协议
//localhost:9090表示请求地址
socket 读写
当建立起连接之后,此时两台主机上的两个进程之间便存在了一个可以进行双向读写的隐式通道,当一方网通道中写入数据,另外一方主机的操作系统就会捕捉到这些传入的数据,并将数据复制到进程的内存中(这当中的弯弯绕绕很多,设计到bio nio 多路复用io),该进程就可以读取数据。
比如客户端通过socket发起了一个http请求,这个http请求显式来看就是一堆有固定格式的字符串,这个固定格式是客户端和服务端商量好的一种格式,服务端一看来的上http请求,那么他也会按照http协议要求的响应格式进行响应。
写入操作:
conn,_:=net.Dial("tcp",""localhost:9090")
//conn.Write() 也可直接写入
write:=bufio.newWriter(conn)
write.Write([]byte("hello"))
读取操作
listen,_:=net.Listen("tcp",""localhost:9090")
conn,_:=listen.Accept()
read:=bufio.newReader(conn)
//返回读取的字节长度 和错误
var buf=[1024]byte{}
len,_:=read.Read(buf[:])