Python之网络编程 socket补充

Posted jacob-yang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python之网络编程 socket补充相关的知识,希望对你有一定的参考价值。

1 文件上传

客户端

import socket
import os
import json
import struct
FILE_PATH = os.path.join(os.path.dirname(__file__), 'demo.mp4')


def socket_client():

    client = socket.socket()

    client.connect(('127.0.0.1',8848))

    #  1.制作字典形式的报头
    head_dic = 
        'MD5': 123244546656,
        'file_name':os.path.basename(FILE_PATH),
        'file_size': os.path.getsize(FILE_PATH),
        'new_file_name': 'demo1.mp4',
    

    # 2. 获取json形式的报头
    head_dic_json = json.dumps(head_dic)

    # 3. 获取bytes形式的报头
    head_dic_json_bytes = head_dic_json.encode('utf-8')

    # 4. 获取bytes报头的总字节数
    head_len = len(head_dic_json_bytes)

    # 5. 将bytes报头的总字节数转化成固定4个字节
    four_bytes = struct.pack('i',head_len)

    # 6. 发送固定的4个字节
    client.send(four_bytes)

    # 7.发送报头
    client.send(head_dic_json_bytes)

    # 8. 发送总数据
    '''
    循环条件设定: 
        1. 根据总子节数: file_size: 493701, 每次循环1024个,
        2. 每次取数据不为空,即可.
    '''
    with open(FILE_PATH,mode='rb') as f1:
        while 1:
            every_data = f1.read(1024)
            if every_data:
                client.send(every_data)
            else:
                break

    client.close()


socket_client()

服务端

import socket
import struct
import json
import os
MY_FILE = os.path.join(os.path.dirname(__file__),'my_file')

def socket_server():
    server = socket.socket()

    server.bind(('127.0.0.1',8848))

    server.listen()

    conn, addr = server.accept()

    # 1. 接收固定长度的4个字节
    four_bytes = conn.recv(4)

    # 2. 利用struct反解
    head_len = struct.unpack('i',four_bytes)[0]

    # 3. 接收bytes类型的报头
    head_dic_json_bytes = conn.recv(head_len)

    # 4. 将bytes类型的报头转化成json
    head_dic_json = head_dic_json_bytes.decode('utf-8')

    # 5. 将json类型报头转化成字典形式的报头
    head_dic = json.loads(head_dic_json)

    # 有一个MD5校验

    # 6. 接收原始数据
    with open(os.path.join(MY_FILE,head_dic['new_file_name']),mode='wb') as f1:

        total_size = 0

        while total_size < head_dic['file_size']:
            every_data = conn.recv(1024)
            f1.write(every_data)
            total_size += len(every_data)

    conn.close()
    server.close()

socket_server()

2 基于udp协议的socket

udp协议: 不可靠,相对来说不安全的协议,面向数据报(无连接)的协议,效率高,速度块.

server

import socket

udp_server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)  # 基于网络,udp协议的socket

udp_server.bind(('127.0.0.1', 9000))

while 1:
    from_client_data = udp_server.recvfrom(1024)
    print(f'来自from_client_data[1]的消息:from_client_data[0].decode("utf-8")')
    to_client_data = input('>>>').strip()
    udp_server.sendto(to_client_data.encode('utf-8'),from_client_data[1])

client

import socket

udp_client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)  # 基于网络,udp协议的socket

while 1:
    to_server_data = input('>>>').strip()
    udp_client.sendto(to_server_data.encode('utf-8'),('127.0.0.1', 9000))
    from_server_data = udp_client.recvfrom(1024)
    print(f'来自from_server_data[1]的消息:from_server_data[0].decode("utf-8")')

3 socketsever 同时接收多方的消息

server

import socketserver

class MyServer(socketserver.BaseRequestHandler): # 继承的类固定的


    def handle(self):  # 必须是这个handle名字.

        while 1:

            from_client_data = self.request.recv(1024).decode('utf-8')  # self.request == conn管道
            print(from_client_data)

            to_client_data = input('>>>').strip()
            self.request.send(to_client_data.encode('utf-8'))



if __name__ == '__main__':

    ip_port = ('127.0.0.1',8848)
    server = socketserver.ThreadingTCPServer(ip_port,MyServer)
    # server.allow_reuse_address = True
    # print(socketserver.ThreadingTCPServer.mro())
    # [ThreadingTCPServer, ThreadingMixIn,TCPServer, BaseServer]
    server.serve_forever()

    # 1. 入口点:ThreadingTCPServer()

client1

import socket

# 1. 创建socket对象(买手机)
phone = socket.socket() # 可以默认不写

# 连接服务器ip地址与端口
phone.connect(('127.0.0.1', 8848))

# 发消息
while 1:
    content = input('>>>').strip()

    phone.send(f'MC骚强:content'.encode('utf-8'))
    # 接收消息
    from_server_data = phone.recv(1024)  # 夯住,等待服务端的数据传过来
    print(f'来自服务端消息:from_server_data.decode("utf-8")')

# 关机
phone.close()

client2

import socket

# 1. 创建socket对象(买手机)
phone = socket.socket() # 可以默认不写

# 连接服务器ip地址与端口
phone.connect(('127.0.0.1', 8848))

# 发消息
while 1:
    content = input('>>>').strip()

    phone.send(f'安安:content'.encode('utf-8'))
    # 接收消息
    from_server_data = phone.recv(1024)  # 夯住,等待服务端的数据传过来
    print(f'来自服务端消息:from_server_data.decode("utf-8")')

# 关机
phone.close()

client3

import socket

# 1. 创建socket对象(买手机)
phone = socket.socket() # 可以默认不写

# 连接服务器ip地址与端口
phone.connect(('127.0.0.1', 8848))

# 发消息
while 1:
    content = input('>>>').strip()

    phone.send(f'怼哥:content'.encode('utf-8'))
    # 接收消息
    from_server_data = phone.recv(1024)  # 夯住,等待服务端的数据传过来
    print(f'来自服务端消息:from_server_data.decode("utf-8")')

# 关机
phone.close()

以上是关于Python之网络编程 socket补充的主要内容,如果未能解决你的问题,请参考以下文章

python网络编程补充

unp第七章补充之socket tcp 产生 rst响应的情况

python3网络编程之socket

python之socket网络编程

Python网络编程之socket应用

python之socket网络编程