网络编程代码

解决粘包

服务端

from socket import *
import subprocess
import struct
import json

server=socket(AF_INET,SOCK_STREAM)
server.bind(('127.0.0.1',8093))
server.listen(5)

while True:
    conn,client_addr=server.accept()
    print(client_addr)

    while True:
        try:
            cmd=conn.recv(8096)
            if not cmd:break

            #ls -l;sadfasdf;pwd;echo 123
            obj=subprocess.Popen(cmd.decode('utf-8'),shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE
                             )
            stdout=obj.stdout.read()
            stderr=obj.stderr.read()

            #1、制作报头
            headers = {
                'filepath': 'a.txt',
                'md5': '123sxd123x123',
                'total_size': len(stdout) + len(stderr)
            }

            headers_json = json.dumps(headers)
        headers_bytes = headers_json.encode('utf-8')

        #2、先发报头的长度
        conn.send(struct.pack('i',len(headers_bytes)))

            #3、发送报头
            conn.send(headers_bytes)

            #4、发送命令的执行结果
            conn.send(stdout)
            conn.send(stderr)
        except ConnectionResetError:
            break
    conn.close()

server.close()

客户端

from socket import *
import struct
import json

client=socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8093))

while True:
    cmd=input('>>: ').strip()
    if not cmd:continue
    client.send(cmd.encode('utf-8'))

    #1、先接收报头的长度
    headers_size=struct.unpack('i',client.recv(4))[0]

    #2、再收报头
    headers_bytes=client.recv(headers_size)
    headers_json=headers_bytes.decode('utf-8')
    headers_dic=json.loads(headers_json)
    print('========>',headers_dic)
    total_size=headers_dic['total_size']

    #3、再收命令的结果
    recv_size=0
    data=b''
    while recv_size < total_size:
        recv_data=client.recv(1024)
        data+=recv_data
        recv_size+=len(recv_data)

    print(data.decode('gbk'))

client.close()

socketserver实现并发

服务端

import socketserver
class MyTcphandler(socketserver.BaseRequestHandler):
    def handle(self):
        while True: #通信循环
            data=self.request.recv(1024)
            self.request.send(data.upper())
if __name__ == '__main__':
    #取代链接循环
    server=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyTcphandler)
    server.serve_forever()

客户端

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))

while True:
    msg=input('>>: ').strip()
    if not msg:continue
    phone.send(msg.encode('utf-8'))
    server_data=phone.recv(1024)
    print(server_data.decode('utf-8'))

phone.close()

 上传下载文件

服务端

import socket
import os
import json
import struct

SHARE_DIR=r'F:Python周末20期day88 上传下载文件SHARE'

class FtpServer:
    def __init__(self,host,port):
        self.host=host
        self.port=port
        self.server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        self.server.bind((self.host,self.port))
        self.server.listen(5)

    def serve_forever(self):
        print('server starting...')
        while True:
            self.conn,self.client_addr=self.server.accept()
            print(self.client_addr)

            while True:
                try:
                    data=self.conn.recv(1024)  #params_json.encode('utf-8')
                    if not data:break
                    params=json.loads(data.decode('utf-8')) #params=['get','a.txt']
                    cmd=params[0] #
                    if hasattr(self,cmd):
                        func=getattr(self,cmd)
                        func(params)
                    else:
                        print('33[45mcmd not exists33[0m')
                except ConnectionResetError:
                    break
            self.conn.close()
        self.server.close()

    def get(self,params): #params=['get','a.txt']
        filename=params[1] #filename='a.txt'
        filepath=os.path.join(SHARE_DIR,filename) #
        if os.path.exists(filepath):
            #1、制作报头
            headers = {
                'filename': filename,
                'md5': '123sxd123x123',
                'filesize': os.path.getsize(filepath)
            }

            headers_json = json.dumps(headers)
            headers_bytes = headers_json.encode('utf-8')

            #2、先发报头的长度
            self.conn.send(struct.pack('i',len(headers_bytes)))

            #3、发送报头
            self.conn.send(headers_bytes)

            #4、发送真实的数据
            with open(filepath,'rb') as f:
                for line in f:
                    self.conn.send(line)

    def put(self):
        pass

if __name__ == '__main__':
    server=FtpServer('127.0.0.1',8081)
    server.serve_forever()

客户端

import socket
import struct
import json
import os

DOWNLOAD_DIR=r'F:Python周末20期day88 上传下载文件DOWNLOAD'

class FtpClient:
    def __init__(self,host,port):
        self.host=host
        self.port=port
        self.client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        self.client.connect((self.host,self.port))

    def interactive(self):
        while True:
            data=input('>>: ').strip() #get a.txt
            if not data:continue
            params=data.split() #parmas=['get','a.txt']
            cmd=params[0] #cmd='get'
            if hasattr(self,cmd):
                func=getattr(self,cmd)
                func(params) #func(['get','a.txt'])

    def get(self,params):
        params_json=json.dumps(params)
        self.client.send(params_json.encode('utf-8'))

        # 1、先接收报头的长度
        headers_size = struct.unpack('i', self.client.recv(4))[0]

        # 2、再收报头
        headers_bytes = self.client.recv(headers_size)
        headers_json = headers_bytes.decode('utf-8')
        headers_dic = json.loads(headers_json)
        print('========>', headers_dic)
        filename = headers_dic['filename']
        filesize = headers_dic['filesize']
        filepath = os.path.join(DOWNLOAD_DIR, filename)

        # 3、再收真实的数据
        with open(filepath, 'wb') as f:
            recv_size = 0
            while recv_size < filesize:
                line = self.client.recv(1024)
                recv_size += len(line)
                f.write(line)
            print('===>下载成功')

if __name__ == '__main__':
    client=FtpClient('127.0.0.1',8081)
    client.interactive()
原文地址:https://www.cnblogs.com/shangdelu/p/8408648.html