灵虚御风
醉饮千觞不知愁,忘川来生空余恨!

导航

 

socket通信

import socket

client = socket.socket() # 拿电话
client.connect(('127.0.0.1',8080))  # 拨号 写的是对方的 IP和端口 port

client.send(b"hello world") # 对别人说话

data = client.recv(1024) # 听别人说话
print(data)
client.close()
client.py
import socket

server = socket.socket()
# 买手机 不传参数用的 TCP协议

server.bind(('127.0.0.1',8080)) # bind((host,port)) 插电话卡

server.listen(5)  # 开机  半连接池

conn,addr = server.accept() # 接听电话 等着别人给你打电话  阻塞

data = conn.recv(1024) # 听别人说话
# 接收1024 个字节数据 阻塞

print(data)
conn.send(b'hello baby~')
# 给别人回话

conn.close() # 挂电话
server.close() # 关机
server.py

TCP粘包问题

import socket

# 买手机
client = socket.socket()

# 拨号
client.connect(("127.0.0.1",8081))

# 说话
# client.send(b"hello sever")
client.send(b'hello')
client.send(b'world')
client.send(b'baby')
# 听话
data = client.recv(1024)

print(data)

# 挂电话
# client.close()
client.py
import socket

# 买手机
server = socket.socket()

# 拨号
server.bind(("127.0.0.1",8081)) # IP 与 port

# 开机
server.listen(5) # 半连接池

# 接通
conn,addr = server.accept()

# 听电话
# data = server.recv(1024)
# print(data)
data = conn.recv(5)  # 听别人说话 接收1024个字节数据          阻塞
print(data)
data = conn.recv(5)  # 听别人说话 接收1024个字节数据          阻塞
print(data)
data = conn.recv(4)  # 听别人说话 接收1024个字节数据          阻塞
print(data)

# 回话
conn.send(b"hello boy")

# 挂电话
# conn.close()
# 关电话
# server.close()
server.py

解决粘包问题

import socket
import struct
import json
# 买手机
client = socket.socket()

# 拨号
client.connect(("127.0.0.1",8081))

# 说话
while True:
    msg = input("cmd:>>>").encode("utf-8")
    if len(msg) == 0:continue
    client.send(msg)

    # 1.先接收字典的报头
    header_dict = client.recv(4)
    # 2.解析报头,获取字典的长度
    dict_size = struct.unpack('i',header_dict)[0] # 解包的时候一定要加上索引 0
    # 3.接收字典数据
    dict_bytes = client.recv(dict_size)
    dict_json = json.loads(dict_bytes.decode("utf-8"))
    # 4.从字典中获取信息
    print(dict_json)
    recv_size = 0
    real_data = b''
    while recv_size < dict_json.get('file_size'): # real_size = 102400
        data = client.recv(1024)
        real_data += data
        recv_size += len(data)
    print(real_data.decode('gbk'))


"""
1.如何将对方发送的数据收干净

"""
client.py
import socket
import subprocess
import json
import struct


# 买手机
server = socket.socket()

# 拨号
server.bind(("127.0.0.1",8081)) # IP 与 port

# 开机
server.listen(5) # 半连接池

# 接通
while True:
    conn,addr = server.accept()
    while True:
        try:
            cmd = conn.recv(1024)
            if len(cmd) == 0:break
            cmd = cmd.decode('utf-8')
            obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
            res = obj.stdout.read() + obj.stderr.read()
            d = {
                "name":"jason",
                "file_size":len(res),
                "info":"hello boy good morning !"
            }
            # 1.先制作一个字典的报头
            json_d = json.dumps(d)
            header = struct.pack('i',len(json_d))
            # 2.发送字典报头
            conn.send(header)
            # 3.发送字典
            conn.send(json_d.encode('utf-8'))

            # 4.再发真实数据
            conn.send(res)
            # conn.send(obj.stdout.read())
            # conn.send(obj.stderr.read())
        except ConnectionResetError:
            break
    conn.close()
server.py

连接循环+通信循环

import socket

# 买手机
client = socket.socket()

# 拨号
client.connect(("127.0.0.1",8081))

while True:
    msg = input("cmd:>>>").encode("utf-8")
    if len(msg) == 0:continue
    client.send(msg)
    data = client.recv(1024)
    print(data)
client.py
import socket
"""
服务端
    固定的ip和port
    24小时不间断提供服务
"""
# 买手机
server = socket.socket() # # 生成一个对象

# 拨号
server.bind(("127.0.0.1",8081)) # IP 与 port # # 绑定ip和port

# 开机
server.listen(5) # 半连接池

# 接通
while True:
    conn,addr = server.accept() # 等到别人来  conn就类似于是双向通
    print(addr) # ('127.0.0.1', 51323) 客户端的地址
    while True:
        try:
            data = conn.recv(1024)
            print(data) #  b''  针对mac与linux 客户端异常退出之后 服务端不会报错 只会一直收b''
            if len(data) == 0:break
            conn.send(data.upper())
        except ConnectionResetError as e:
            print(e)
            break
    conn.close()
server.py

 

import struct

res = "sdhsfjdshjflkjdsafhjdsajflkhdlkjafhkjsadhfkjjsadkfhkjlsadhkfhksadfjjhsadfsdkaf"

print("最原始的",len(res))# 最原始的 78

# 当原始数据特别大的时候, i 模式打包不了,需要更换模式

# 如果遇到数据量特别大的情况 该如何解决?

d = {
    'name':"jason",
    "file_size":34355555555555555,
    "info":"为大家的骄傲"
}

import json
json_d = json.dumps(d)
print(len(json_d))# 97

resl = struct.pack('i',len(json_d))
print(len(resl))# 4

res2 = struct.unpack('i',resl)[0]
print("解包之后",res2)
# 解包之后 97
struct模块.py
import subprocess

cmd = input("cmd:>>>").strip()

obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)

print(obj.stdout.read().decode('gbk')) # 正确命令返回的结果

print(obj.stderr.read().decode('gbk'))  # 错误的命令返回的结果

# subprocess获取到的数据 拿完就没有了  不能重复的拿
print(obj.stdout.read().decode('gbk'))  # 正确命令返回的结果
print(obj.stderr.read().decode('gbk'))  # 错误的命令返回的结果
subprocess复习.py
Socket(套接字)
   127.0.0.1本机回还地址
    只能自己识别自己 其他人无法访问

    send与recv对应
    不要出现两边都是相同的情况

    recv是跟内存要数据
        至于数据的来源 你无需考虑

TCP特点
    会将数据量比较小的并且时间间隔比较短的数据
    一次性打包发送给对方


socket最简单版本


解决粘包问题的最复杂版本


from socket import SOL_SOCKET,SO_REUSEADDR
sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) # 就是他,在 bind前面加

解决粘包问题
    服务端
        1.先制作一个发送给客户端的字典
        2.制作字典的报头
        3.发送字典的报头
        4.发送字典
        5.再发真实数据

    客户端
        1.先接受字典的报头
        2.解析拿到字典的数据长度
        3.接受字典
        4.从字典中获取真实数据的长度
        5.接受真实数据

写一个上传电影的功能
    1.循环打印某一个文件夹下面的所有的文件
    2.用户选取想要上传的文件
    3.将用户选择的文件上传到服务端
    4.服务端保存该文件




1.直接获取数据1024
2.制作一个数据的报头
3.先发个字典  然后再发真实数据
笔记总结

 

posted on 2022-03-28 14:08  没有如果,只看将来  阅读(20)  评论(0编辑  收藏  举报