1. C/S 架构

C/S 架构即客户端/服务端架构,B/S 架构(浏览器与服务端)也是 C/S 架构的一种。

C/S 架构与 socket 的关系:学习 socket 可以完成 C/S 架构的开发。

2. osi 七层

一个完整的计算机系统由硬件、操作系统以及应用软件三部分组成,但是不能与其他计算机通信,这时就需要用到互联网。

互联网的核心是由一堆协议组成,协议就是标准。所有的计算机按照统一的标准去收发信息从而完成通信。

按照分工不同,将互联网协议从逻辑上划分为七层:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层

Clos架构怎么实现冗余 clos网络架构_Clos架构怎么实现冗余

3. socket 层

C/S架构软件属于应用层,是基于网络进行通讯的。网络的核心是协议,那么要想开发一款应用软件,就需要遵循 TCP/UDP协议。

然而 TCP/UDP 知识何其多,需要花费大量的时间去学习,大大减小了开发效率。

问题:那到底什么是 socket 呢?

socket 是应用层与传输层(TCP/UDP协议)通讯的中间软件抽象层。它封装了 TCP/UDP协议,并提供一组接口,供开发软件使用。

开发一款软件只需调用接口,就能遵循 TCP/UDP协议,我们无需再深入理解 TCP/UDP协议。

也人说 socket 是 ip + port,ip 用来标识一台主机位置,配置在网卡上。而 port 用来标识计算机上的一个程序,由应用程序开启,两者结合标识了独一无二的一个应用程序。

程序的 pid 是应用程序进程或线程的标识,一个程序往往有多个 pid。

Clos架构怎么实现冗余 clos网络架构_网络_02

4. 套接字发展历史及分类

socket 又称为套接字,起源于 20世纪70年代加利福利亚伯克利分校版本的 Unix,即 BSD Unix。又称为 伯克利套接字或 BSD 套接字

刚开始套接字被设计为在同一主机上多个应用程序之间的通讯,也被称为进程间通讯或 IPC

分类

  • 基于文件类型的套接字家族
  • **家族名字:**AF_UNIX
  • unix 一切皆文件,基于文件的套接字就是调用底层的文件系统来获取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信。
  • 基于网络类型的套接字家族
  • **家族名字:**AF_INET

5. 套接字工作流程

服务器端:

先初始化 socket,然后与端口绑定(bind),对端口进行监听(listen),调用 accept 阻塞,等待客户连接。

客户端:

初始化一个 socket,然后连接服务器(connect),如果连接成功,那么客户端与服务端连接的连接就建立好了。

客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。

Clos架构怎么实现冗余 clos网络架构_tcp/ip_03

服务端:

import socket
ip_port = ('127.0.0.1', 8000)
back_log = 5
buffer_size = 1024
# socket.AF_INET:基于网络  socket.SOCK_STREAM:tcp 协议
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   
s.bind(ip_port)     # 手机插卡,如果元组为('',9000)表示本机所有的网卡,相当于0.0.0.0
s.listen(back_log)     # 手机开机,5 表示用于 tcp 连接的优化
conn, addr = s.accept()  # 等电话
print('来自%s的电话' % addr[0])
msg = conn.recv(buffer_size)   # 收消息
print('客户端发来信息:', msg)

conn.send(msg.upper())   # 发消息

conn.close()    # 挂电话
s.close()   # 关机
来自127.0.0.1的电话
客户端发来信息: b'hello'

客户端:

import socket

ip_port = ('127.0.0.1', 8000)
buffer_size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   # 买手机
s.connect(ip_port)      # 拨电话
s.send('hello'.encode('utf-8'))     # 发消息
feedback = s.recv(buffer_size)     # 收信息
print('接收到服务端的信息%s' % feedback.decode('utf-8'))
s.close()   # 挂电话
接收到服务端的信息HELLO