socket 模块
我们知道基于网络编写程序时,需要使用 OSI七层协议里的七层,每一层都要写。很复杂很繁琐。
socket 模块相当于集成了这一块,封装了复杂的接口提空了简单快捷的接口。
socket套接字简介
基于文件类型的套接字家族(单机)
AF_UNIX
基于网络类型的套接字家族(联网)
AF_INET
代码实操
cs架构的软件都应该考虑到服务端,因为只有有了服务场所,才能提供服务
# 1.产生一个socket对象并指定采用的通信版本和协议(TCP)
server = socket.socket() # 括号内不写参数 默认就是TCP协议 family=AF_INET基于网络的套接字 type=SOCK_STREAM流式协议即TCP
# 2.绑定一个固定的地址(服务端必备的条件)
server.bind(('127.0.0.1', 8080)) # 127.0.0.1为本地回环地址 只有自己的电脑可以访问
# 3.设立半连接池(暂且忽略)
server.listen(5)
# 4.等待接客
sock, addr = server.accept() # return sock, addr 三次握手 建立链接
print(sock, addr) # sock就是双向通道 addr就是客户端地址
# 5.服务客人
data = sock.recv(1024) # 接收客户端发送过来的消息 1024字节
print(data.decode('utf8'))
sock.send('滚开我不开心'.encode('utf8')) # 给客户端发送消息 注意消息必须是bytes类型
# 6.关闭双向通道
sock.close() # 四次挥手 关闭链接
# 7.关闭服务端
server.close()
# 客户端
import socket
# 1.生成socket对象指定类型和协议
client = socket.socket()
# 2.通过服务端的地址链接服务端
client.connect(('127.0.0.1', 8080))
# 3.直接给服务端发送消息
client.send('今天你吃饭了吗'.encode('utf8'))
# 4.接收服务端发送过来的消息
date = client.recv(1024)
print(date.decode('utf8'))
# 5.断开与服务端的链接
client.close()
数据交互循环
# 1.解决信息固定的问题
利用input获取用户输入
# 2.解决通信循环的问题
将双方用于数据交互的代码循环起来
# 服务端
while True:
data = sock.recv(1024) # 获取别人说的什么
print(data.decode('utf8')) # 解码别人说的啥
msg = input('请回复>>>:').strip()
sock.send(msg.encode('utf8')) # 回复别人的话,因为基于网络传输,使用二进制编码
# 客户端
while True:
msg = input('请输入你要发送的信息>>>:').strip()
client.send(msg.encode('utf8')) # 给服务端发送信息
data = client.recv(1024) # 接收服务端回复消息
print(data.decode('utf8'))
代码优化
1、发送信息不能为空
统计长度然后进行判断(len)
2、苹果电脑 反复重启服务端可能会发生报错: address in use
解决方法:
# 在最上面放一个
from socket import SOL_SOCKET,SO_REUSEADDR
# 在bind上面放
server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
当客户端异常断开的情况下 如何让服务端继续服务其他客人
"""
如果在windows客户端异常处理退出之后服务端就会直接报错,直接加上异常处理 break结束退出内循环 跳到外循环 接待另一个客人
处理方式: 异常处理 """
while True:
sock, addr = server.accept()
try:
data = sock.recv(1024) # 获取别人说的什么
print(data.decode('utf8')) # 解码别人说的啥
msg = input('请回复>>>:').strip()
sock.send(msg.encode('utf8')) # 回复别人的话,因为基于网络传输,使用二进制编码
except Exception:
break
"""
如果是mac或linux服务端,就会接收到一个空的信息
处理方式: len判断 """
while True:
sock, addr = server.accept()
try:
data = sock.recv(1024) # 获取别人说的什么
if data(len) == 0:
break
print(data.decode('utf8')) # 解码别人说的啥
msg = input('请回复>>>:').strip()
sock.send(msg.encode('utf8')) # 回复别人的话,因为基于网络传输,使用二进制编码
except Exception:
break
半连接池
listen(5)
py文件默认只能同时只能运行一次,如果想要单独分开运行多次:
Edit Configuration选择all
# 半连接池
设置最大等待人数 >>>: 节省资源,提升效率
标签:socket,utf8,sock,server,模块,data,服务端
From: https://www.cnblogs.com/LiaJi/p/16896480.html