2.scoket 网络编程技术
一、网络编程技术概述
1.软件开发架构
应用类 -- C/S 架构
C/S
:客户端与服务器端架构,客户端 泛指 应用程序 EXE ,程序需要先安装才能运行,对系统环境依赖较大。Web 类 -- B/S 架构
B/S
:浏览器端与服务器端架构,用户通过 HTTP 请求服务器端相关的资源。
2.网络通信要素
- IP 地址 :互联网协议地址
- 端口 :设备与外界通讯交流的出口
- 传输协议
提示
IP 地址 精确到 具体的一台电脑,而 端口 精确到 具体的程序
3.通信协议
通信协议:互联网的核心就是由一堆协议组成,协议就是标准。
七层网络协议模型
二、Socket 通信流程
1.Socket 概念
Socket
:是应用层与 TCP/IP 协议族通信的中间软件抽象层,它是一组接口。
在设计模式中,Sorcket 其实就是一个门面模式,它把复杂的 TPC/IP 协议族隐藏在 Socket 接口后面,对用户来说,一组简单的接口就是全部,让 Socket 去组织数据,以符合指定的协议。
提示
1.websocket
(应用层) :通过 HTTP 协议进行传输,
2.socket
(传输层) :通过 TCP 协议进行传输
2.Socket 实现方式:TCP 协议与 UDP 协议
TCP
协议 :可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。主要用途:Web 浏览器、电子邮件、文件传输程序
UDP
协议 : 不可靠的、无连接的服务,传输效率高,一对一、多对多、一对多、多对一、面向报文,尽最大的努力服务,无拥塞控制。主要用途:域名系统、视频流、IP 语音。
TCP
和UDP
都是 传输层 的。
TCP 协议流程图:
3. Socket 通信流程
服务器根据地址类型、Socket 类型、协议 创建 Scoket ;
服务器为 socket 绑定 IP 地址和端口号 ;
服务器 socket 监听端口号请求 ,随时准备 接收客户端发送来的连接,这个时候服务器端的 Socket 并没有打开;
客户端创建 Socket ;
客户端打开 socket ,根据服务器 IP 地址和 端口号 试图连接服务器 socket ;
服务器 Scoket 接收到客户端的 socket 请求,被动打开,开始接收客户端请求,直到客户端返回连接信息。这个时候 socket 进入阻塞状态。
阻塞状态
:即accept()
方法一直等到客户端返回连接信息后才返回,开始接收下一个客户端连接请求。**客户端连接成功,****向服务器发送连接状态信息**。
服务器 accept 方法返回,连接成功;
客户端向 socket 写入信息(或服务端向 socket 写入信息);
服务器读取信息(客户端读取信息);
客户端关闭;
服务器关闭。
Socket 常用方法
1.Python 的 Socket 编程
- 低级别的网络服务 支持基本的
Socket
,它提供了标准的 BSD Socket API ,可以访问底层操作系统 Socket 接口的全部方法。 - **高级别的网络服务 **模块
SocketServer
, 它提供了服务器中心类,可以简化网络服务器的开发。
2.什么是 Socket 编程
socket
:又称 ”套接字“ ,应用程序通常通过 ”套接字“ 向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。
使用 socket()
函数来 创建 套接字
socket.socket([family[,type[,proto]]])
family
:套接字家族可以使 AF_UNIX 或者 AF_INET .type
:套接字类型可以根据是面向 连接 的还是 非连接 分为 SOCK_STREAM 或 SOCK_DGRAM .protocol
:一般不填默认为 0 。
3. Socket 服务端
- 使用 socket 模块 的 socket 函数 来创建一个
socket 对象
。socket 对象可以通过调用其他函数来设置一个 socket 服务。 - 可以通过调用
bind(hostname,port)
函数来指定服务的 port (端口)。 - 调用 socket 对象 的
accept 方法
。该方法等待客户端的连接,并返回 connection 对象,表示已连接到客户端。
4. Socket 客户端
socket.connect(hosname, port)
方法 打开一个 TCP 连接到主机为 hostname 端口为 port 的服务商。- 连接后就可以从服务端获取数据,记住,操作完成 后需要 关闭连接
5.案例一(单个连接)
服务端:
import socket
ip_port = ('127.0.0.1', 9999)
# 1.创建 socket 对象
sk = socket.socket()
# 2.绑定 ip port
sk.bind(ip_port)
# 3.开启监听
sk.listen()
print("---服务已经启动---")
# 4.阻塞 等待连接 返回:socket连接对象(套接字)和 客户端IP
conn, addr = sk.accept()
print("客户端的地址 >>> :", addr)
# 5.接收数据---客户端数据
# recv() 需要文件宽度作为参数,一般为 1024
# 使用 decode() 进行解码
receive_data = conn.recv(1024).decode("utf-8")
print("接收客户端的数据 >>> :", receive_data)
# 6.发送数据
send_data = input("请输入 >>> :")
# sendall() 要求是 byte 类型,使用encode() 进行字符转换
conn.sendall(send_data.encode("utf-8"))
# 7.关闭 socket
conn.close()
客户端:
import socket
# 1.创建 socket
sk = socket.socket()
# 2.连接到服务器
sk.connect(('127.0.0.1', 9999))
print("服务端连接成功")
# 3.发送数据
send_data = input("请输入 >>> :")
# sendall() 要求是 byte 类型,使用encode() 进行转码
sk.sendall(send_data.encode('utf-8'))
# 4.接收服务端数据
server_data = sk.recv(1024).decode("utf-8")
print("接收服务端的数据 >>> :", server_data)
# 5.关闭 socket
sk.close()
案例二(多个连接):
服务端:
import socketserver
# 1.需要继承一个类
class sqServer(socketserver.BaseRequestHandler):
def handle(self):
print("聊天服务器上线了")
while True:
try:
# 接收客户端数据
self.client_data = self.request.recv(1024)
print(self.client_data.decode("utf-8"))
# 发送数据
send_data = input("请输入 >>> :")
self.request.sendall(send_data.encode("utf-8"))
except ConnectionResetError as e:
print("一个客户端关闭了连接")
break
self.request.close()
# 2.创建服务
# ThreadingTCPServer 是使用多线程
# ForkingTCPServer 是使用多进程处理并发
server = socketserver.ThreadingTCPServer(("127.0.0.1", 9998), sqServer)
# 3.一直在线
server.serve_forever()
客户端:
import socket
# 1.创建 socket
sk = socket.socket()
# 2.连接到服务器
sk.connect(('127.0.0.1', 9998))
print("服务端连接成功")
# 3.发送数据
while True:
send_data = "老王:" + input("请输入 >>> :")
if send_data == '老王:' + 'exit':
break
else:
# sendall() 要求是 byte 类型,使用encode() 进行转码
sk.sendall(send_data.encode('utf-8'))
# 4.接收服务端数据
server_data = sk.recv(1024).decode("utf-8")
print("接收服务端的数据 >>> :", server_data)
# 5.关闭 socket
sk.close()