计算机基础知识32

Socket抽象层(socket编程)

Socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单 的接口供应用层调用已实现进程在网络中通信

socket () 对象

bind () 函数来绑定

listen () 监听,等别人电话

accept()接收,已发送真实数据,真正等待客户端发信息

read()接收,真正拿到客户端信息 recv

write()send过程,发送,回应客户端

read()不会立刻断掉

close()断开

socket抽象层把复杂的事已做比如(三次握手四次挥手),我们不需要操心,只需简单的 发送和接收

基于TCP协议的套接字(socket)编程

基于文件类型的套接字家族:

套接字家族的名字:AF_UNIX

基于网络类型的套接字家族:

套接字家族的名字:AF_INET

客户端先发送消息,需要服务端先运行起来

"""服务端代码:"""

python 复制代码
import socket  # 导入socket模块
from socket import AF_INET
server=socket.socket(family=AF_INET, type=socket.SOCK_STREAM) 
# AF_INET, type=SOCK_DGRAM: 基于UDP协议的
server.bind(('127.0.0.1', 8000))     # 绑定IP地址和port
# 绑定谁,谁就是服务端,可用你的客户端给他的服务端发信息
server.listen(3)  # 服务端做监听,也称为是半链接池(服务端能够同时等待客户端的数量)
sock, addr = server.accept()  # sock:当前链接的客户端的链接, addr:就是客户端的地址:ip,port
data=sock.recv(1024) # 接收的数据类型是bytes类型,二进制的 1024 代表接收的最多的字节数
print("接收客户端的数据:",data)
sock.send(data.upper()) # 发送的数据是字节类型的
sock.close()   # 关闭链接
server.close()

sock, addr = server.accept() 代码会卡住,等待客户端开发链接和发送信息

"""客户端代码"""

python 复制代码
import socket
from socket import AF_INET
client=socket.socket(family=AF_INET, type=socket.SOCK_STREAM)
# socket.socket()
client.connect(('127.0.0.1', 8000))
# 开始给服务端发送消息
client.send('hello'.encode('utf-8'))
# 接收服务端发来的消息
data=client.recv(1024)
print("服务端发来的消息:", data)
client.close()

加上通信和通信循环

python 复制代码
"""服务端"""
import socket 
from socket import AF_INET
server=socket.socket(family=AF_INET, type=socket.SOCK_STREAM) 
server.bind(('127.0.0.1', 8000))     
server.listen(3)
while True:  
    sock, addr = server.accept()  
    while True:
        try:
            data=sock.recv(1024) 
            print("接收客户端的数据:",data)
            sock.send(data.upper()) 
        except Exception as e:
            print(e)     # 答应出错误
            break
    sock.close()   
server.close()
python 复制代码
"""客户端"""
import socket
from socket import AF_INET
client=socket.socket(family=AF_INET, type=socket.SOCK_STREAM)
client.connect(('127.0.0.1', 8000))
while True:
    send_data = input('请输入你要发送给服务端的数据:')
    client.send(send_data.encode('utf-8'))
    data=client.recv(1024)      # 接收服务端发来的消息
    print("服务端发来的消息:", data)
client.close()

1、在accept()用while True循环,可支持多个客户端的数据(一个服务端)

2、当前:客户端只能说一句话

在send()用while循环,把发送的信息用input写活,可以多次发送信息了

3、问题:客户端还可以发送信息,但是此时服务端接收一个就已经close

在第一个close之前再一次循环,accept下

4、客户端发送的数据是空时,一个客户端出现了问题,整个服务器都将会报错

用异常捕捉,try

基于UDP协议的套接字编程

"""服务端"""

python 复制代码
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # 数据报协议-》UDP
server.bind(('127.0.0.1', 8080))
while True:
    """client_addr: 客户端的地址"""
    data, client_addr = server.recvfrom(1024) # 接收的最大字节数
    print('===>', data, client_addr)
    server.sendto(data.upper(), client_addr)
server.close()

"""客户端"""

python 复制代码
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # 数据报协议-》UDP
while True:
    msg = input('>>: ').strip()  # msg=''
    client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080))
    data, server_addr = client.recvfrom(1024)
    print(data)
client.close()

粘包现象

python 复制代码
import subprocess
res = subprocess.Propen(tasklist,shell=True,stderr=subprocess.PIPE,stdout=subprocess.PIPE)
# shell脚本(linux)
# tasklist命令,其实它是一个shell语言,bash解释器
# 正确stderr=subprocess.PIPE,错误stdout=subprocess.PIPE

粘包:管道里的数据没有取完,造成数据的丢失,但是可以多次取

在内存一定的情况下解决粘包问题:

1、知道服务端发过来字节的大小/每次接收的字节大小=总次数

2、struct模块

python 复制代码
import struct
res = struct.pack('i',1024)    # 1024给打包
print(res)   # b'\x00\xo4\xoo... 二进制
print(len(res))    # 4 不管输入多大,固定长度还是4

解包

python 复制代码
res1 = struct.unpack('i',res)
print(res1[0])   # 1024

过程:1、把服务端发过来字节打包,长度4

2、客户端 sock.recv(4) 只接4个

3、unpack('i',res) 解包/大小

4、得到总次数

TCP的流式协议

python 复制代码
sock,addr = sever.accept()
print('jerry',encode('utf-8'))

在短时间内,短时间客户端可发送多个数据,服务端可以一次性接收完

今日思维导图:

相关推荐
雯宝3 小时前
mnt_init 函数
linux
律宏阔9 小时前
WSL Docker 端口明明空闲,但就是绑不上端口
linux·windows
律宏阔9 小时前
WSL 突然断网,无法 ping 内网或外网
linux·windows
穷人小水滴9 小时前
用容器编译 VirtualBox 虚拟机软件 (ArchLinux, podman)
linux·容器·virtualbox
乱码三千10 小时前
如何优雅地直连无公网 IP 的远程 GPU 服务器
linux·人工智能·程序员
yunwei3710 小时前
使用 eBPF 跟踪 Nginx 请求
linux·后端·性能优化
yunwei3710 小时前
使用 eBPF 跟踪 MySQL 查询
linux·后端·性能优化
yunwei3710 小时前
eBPF 示例教程:使用 XDP 捕获 TCP 信息
linux·后端·性能优化
GeW10 小时前
制造业高端化,为什么必须重估Linux和数据库?
linux
百万蹄蹄向前冲10 小时前
双端同步!云服务器装最新Node.js v26.10全过程追踪
服务器·人工智能·node.js