day33

今日内容:

客户端:

import socket
import struct
from 粘包问题 import common

client = socket.socket()

try:
client.connect(("127.0.0.1", 1588))
print("服务器链接成功")
while True:
msg = input("请输入指令:q为退出:").strip()
if not msg: break
if msg == "q": continue
# 发送指令
# 先发长度

len_bytes = struct.pack("q", len(msg.encode("utf-8")))
client.send(len_bytes)
# 再发指令
client.send(msg.encode("utf-8"))

data = common.recv_data(client)
print(data.decode("GBK"))
# # 先收长度再收数据,解决粘包问题
# # 接收长度数据,固定位8个字节
# len_bytes = client.recv(8)
# # 把接收到的字节进行反解,用unpack,按照规定服务器保持一致,转码后是元组所以取0号位即数据
# len_size = struct.unpack("q", len_bytes)[0] # 转换为整形
# print("服务器返回了%s长度的数据" % len_size)
# # 如果数据量过大,则不能一次收完,必须循环一次收一部分
# buffer_size = 1024 # 缓存区
# recv_size = 0 # 所收数据真实长度
# data = b"" # 最终的数据
# while True:
# # 循环接收真实数据
# # 如果剩余数据长度 大于缓存区大小,则读取缓存区,有多大读多大
# if len_size - recv_size >= buffer_size:
# temp = client.recv(buffer_size)
# else:
# temp = client.recv(len_size - recv_size) # 否则就是剩余长度小于缓存区大小,有多少收多少
# recv_size += len(temp) # 所收长度每次在上一次上增加,最终等于真实数据长度
# data += temp
# # 当已接收大小等于数据总大小则跳出循环
# if recv_size == len_size:
# break

# print(data.decode("gbk"))
client.close()
except ConnectionRefusedError as e:
print("连接服务器失败!", e)
except ConnectionResetError as e:
print("服务器挂了!")
client.close()
服务器端循环发送
while True:
client, addr = server.accept()
print("链接成功,开始服务!")
while True:
try:
data = client.recv(1024).decode("utf-8")



if not data:
break
print(data)
p = subprocess.Popen(data, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
data = p.stdout.read()
err_data = p.stderr.read()


# #解决粘包问题,在发送真实数据之前先发送长度,然后发送数据,
# # 此时就需要固定字节的长度,即用struct模块,将数据转为字节,并且固定长度
len_size = len(data)+len(err_data) #计算数据长度
print("服务器返回了: %s" % len_size)
# 先发数据长度
len_bytes = struct.pack("q",len_size) #把数据长度转变为规定长度的字节长度
# 在发送真实数据长度之前发送 数据长度
client.send(len_bytes) #即发送把规定字节长度的数据长度
# 发真实数据
client.send(data + err_data) #返回的结果就是二进制,不需要转码直接发
# except ConnectionRefusedError as e:
# print("!!", e)
except ConnectionResetError as e:
print("客户端挂了", e)
client.close()
break
client.close()

UDP服务器:

from socket import *
# 创建udp的socket,必须手动指定
server = socket(AF_INET, SOCK_DGRAM)
server.bind(("127.0.0.1", 1688))
while True:
    data, addr = server.recvfrom(1024)  # 接收数据
    print("收到来自%s的消息:" % (addr, data))
 

UDP客户端:

from socket import *
client = socket(AF_INET, SOCK_DGRAM)
# UDP不需要建立链接
# 发送数据时 要制定接受方地址
# 参数一为要发送的内容,然后点语法encode("utf-8")为转码,第三位为ip地址和端口 必须为元组
client.sendto("hello".encode("utf-8"), ("127.0.0.1", 1688))
data, addr = client.recvfrom(1024)  # 接受的数据
print("收到来自%s的消息:" % (data, addr))
client.close()

原文地址:https://www.cnblogs.com/Fzhiyuan/p/10952701.html