协议:一组规范。要求使用协议的双方,必须要严格准守。
常见协议: 应用层: http、ftp、ssh、telnet、NFS。。。
传输层:TCP、UDP
网络层;IP、ICMP、IGMP
链路层:RARP、ARP
网络分层模式:
OSI 七层模型: 物、数、网、传、会、表、应
TCP/IP 四层模型: 链、网、传、应
数据通信流程:
封装过程:数据 ——> 应用层 ——> 传输层 ——> 网络层 ——> 链路层 ——> 网卡
。。。。进入网络环境传输。
解封过程:网卡——> 链路层 ——>网络层——> 传输层——> 应用层 ——> 数据
链路层:
【mac地址】 —— 【目标mac地址】
ARP协议:借助 IP 获取 mac 地址
网络层:
Ip地址: 在网络环境中唯一标识一台主机。
【主机】 —— 【目标主机】
传输层:
端口(port)号:在一台网络主机中唯一标识 一个 进程。
【进程】 —— 【目标进程】
Ip + port = 在网络中 唯一标识一个 进程。 —— 套接字!!!
--------------------------------------以上为 内核 完成操作。
应用层:(非必须协议)
【应用数据】—— 【目标应用数据】
socket 套接字: 伪文件。—— 内存。 双向全双工
在一次网络通信过程中,参与通信的 socket 必须 “成对”出现。
socket 内核实现原理:
一个 socket 内部相当于有 两个 channel (一个读、另一个写), 外部对这两个 channel 不可见。
Ip + port = 在网络中 唯一标识一个 进程。 —— 套接字!!!
网络应用程序设计模式:
优点 缺点
C/S: 缓冲大量数据、协议选择灵活 用户安全性较差、不能跨平台、开发工作量大
B/S: 用户安全性较好、能跨平台、开发工作量小 不能缓冲大量数据、协议选择受浏览器限制
TCP-CS模型- server端 实现流程:
1. 创建监听器:
Listener, err := net.Listen("tcp", "127.0.0.1: 8000")
func Listen(network, address string) (Listener, error)
参1:协议:tcp、udp (小写)
参2:IP:服务器自己的 IP 和 port
port “127.0.0.1: 8000”
port: 取值:> 4000 , 不要使用 8080 。 上限 65535
返回值: 监听器。(interface)
type Listener interface {
Accept()
Close()
Addr();
}
2. 启动监听: Accept() —— 造成当前进程 阻塞!
func (Listener) Accept() (Conn, error)
参:无参
返回值: Conn, err
type Conn interfase {
Read()
Write()
Close()
}
for {
3. 读 客户端数据 read
4. 写 数据给 客户端 write
}
5. Close() —— Listener、Conn
测试:
借助 Linux 下 的 nc 命令 充当客户端。
语法:nc“空格” IP地址 “空格” 端口号 “回车”
TCP-CS模型- client端 实现流程:—— 替代 nc 命令。
1. net.Dial() —— 不会阻塞
func Dial(network, address string) (Conn, error)
参1:选用的协议:“tcp”
参2:服务器的 IP:port
返回值:用于跟服务器进行数据通信的 socket
for {
2. 写数据给服务器 conn.write()
3. 读服务器回发的数据 conn.read()
}
4. close 关闭 conn.Close()
TCP-CS模型-并发server 实现流程:
1. 创建监听器: net.Listen() ——> listener
for {
2. 循环监听客户端连接请求: listener.Accept() ——> conn
3. 调用函数实现 客户端 - 服务器 数据交互。 func HandlerConnect(conn net.Conn)
}
4. 实现 该通信函数
func HandlerConnect(conn net.Conn)
{
5. 关闭 conn defer conn.Close()
6. conn.RemoteAddr().string() 查看当前客户端 Addr 信息(Ip:port)
for {
7. 读客户端发送的数据
8. 使用 数据 小写 —— 大写 A -- a 32
toUpper()
9. 写客户端发送数据
}
}
【网络socket通信,重要结论】:conn.Read() 如果读到 0 说明对端关闭!!!!