Python实现一个简单的socket服务器


该服务器主要实现从客户端拷贝文件(.c)到指定目录,再把这个文件发送给服务器,并让服务器执行脚本,执行脚本需要用到这个.c文件进行编译,编译完告诉客户端,并且把编译生成的多个文件夹(含文件)发送给客户端查看。

1、客户端


import socket  # Import socket module
import time, os
import shutil
import tools
primary_dir0 = r"D:\zqw\pa\pa\RSlistLib.c"
target_dir1 = r"D:\zqw\py\pyserver\clientSend"

path0 = r'D:\zqw\py\pyserver\clientRecv\shareData\Outdir'
path1 = r'D:\soft\Wecon PLC Editor2\ASM2BIN'




if __name__ == "__main__":
    sock = socket.socket()  # Create a socket object
    host = '192.168.51.177'  # Get local machine name
    port = 12312
    sock.connect((host, port))
    try:
        shutil.copy(primary_dir0, target_dir1)
    except IOError as e:
        print("Unable to copy file. %s" % e)
    except:
        print("Unexpected error:")
    sock.send(b"Hello server!")
    time.sleep(0.1)
    while 1:
        url = target_dir1
        # 用来存放所有的文件路径
        file_list = []
        # 用来存放所有的目录路径
        dir_list = []
        # 用来存放目录路径
        dir_lists = []
        name = url.split("\\")[-1]
        tools.get_file_path(url, file_list, dir_list, name, dir_lists)
        print(file_list)
        print(dir_list)
        print(dir_lists)  # 共享目录的路径
        dir = os.listdir(url)
        for dir in dir_lists:
            sock.send(b'send_client_dir')
            time.sleep(0.3)
            sock.send(bytes(dir.encode('utf-8')))
            time.sleep(0.3)
        for i in file_list:
            sock.send(b'send_client_file')
            time.sleep(0.3)
            sock.send(bytes(i.encode('utf-8')))
            time.sleep(0.3)
            print(i)
            with open(i, "rb") as in_file:  # 这里修改文件
                data = in_file.read(1024)
                while data:
                    sock.send(data)
                    print(f"Sent {data!r}")
                    data = in_file.read(1024)
            print("Done sending")
            time.sleep(0.3)
            sock.send(b'end_send_client_file')
        time.sleep(0.3)
        sock.send(b'end_client_sends')
        time.sleep(0.3)
        sock.send(b'run_bat')
        # break
        #接收
        while 1:
            url = r'D:\zqw\py\pyserver\clientRecv'  # 保存路径
            data = sock.recv(1024)
            # print(data.decode())
            if data == b'send_server_dir':
                data = sock.recv(1024)
                path = data.decode()
                if os.path.exists(url + '\\\\' + path):
                    print('exist')
                else:
                    os.makedirs(url + '\\\\' + path)
            if data == b'send_server_file':
                data = sock.recv(1024)
                file_name = data.decode()
                print(file_name)
                with open(url + '\\\\' + file_name, "wb") as out_file:
                    while True:
                        data = sock.recv(1024)
                        print(f"data={data}")
                        if data == b'end_server_send':
                            print("client successfully recv the file")
                            # tools.func_copy(path0, path1)
                            # print("copy successfully")
                            # time.sleep(0.2)
                            tools.copy_demo(path0, path1)
                            time.sleep(0.1)
                            break
                        out_file.write(data)
                    out_file.close()


















2、服务器



# 第3版
import subprocess
import time
import os
import socket  # Import socket module
import tools


if __name__ == "__main__":

    ONE_CONNECTION_ONLY = (
        True  # Set this to False if you wish to continuously accept connections
    )

    # filename = "Example"
    port = 12312  # Reserve a port for your service.
    sock = socket.socket()  # Create a socket object
    host = '192.168.51.177'  # local IP
    print('Local:'+host+":"+str(port))
    sock.bind((host, port))  # Bind to the port

    while True:
        sock.listen(5)  # Now wait for client connection.
        try:
            print("Server listening....")
            conn, addr = sock.accept()  # Establish connection with client.
            print(f"Got connection from {addr}")#('127.0.0.1', 50223)

            while 1:
                url = r'D:\PyCharm2019\PycharmProjects\pyserver2\serverRecv'  # 保存路径
                data = conn.recv(1024)
                print(data.decode())
                if data == b'send_client_dir':
                    data = conn.recv(1024)
                    path = data.decode()
                    if os.path.exists(url + '\\\\' + path):
                        print('exist')
                    else:
                        os.makedirs(url + '\\\\' + path)
                if data == b'send_client_file':
                    data = conn.recv(1024)
                    file_name = data.decode()
                    print(file_name)
                    with open(url + '\\\\' + file_name, "wb") as out_file:
                        while True:
                            data = conn.recv(1024)
                            print(f"data={data}")
                            if data == b'end_send_client_file':
                                print("server successfully recv the file")
                                time.sleep(0.1)
                                break
                            out_file.write(data)
                        out_file.close()
                if data == b'end_client_sends':
                    break

            while True:
                data = conn.recv(1024)
                print(f"Server received {data}")
                if data==b'run_bat':#D:\code\LX5VBuild2\build.bat   F:\pyserver\run.bat
                    p = subprocess.Popen(r'D:\code\LX5VBuild2\build.bat',stdout=subprocess.PIPE,stderr=subprocess.PIPE)
                    p.wait()#让脚本执行完再走
                    time.sleep(0.1)
                    # time.sleep(2)#改动的
                    # result = res.stdout.readlines()
                    # for res in result:
                    #     t=res.decode('utf-8')#.replace('\r\n','')#UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd2 in position 0: invalid continuation byte
                    #     print(t)
                    #     conn.send(bytes(t.encode('utf-8')))
                    # time.sleep(0.1)
                    conn.send(b'run_end')
                    time.sleep(0.5)
                    #url=r"D:\PyCharm2019\PycharmProjects\pyserver2\shareData" #D:\code\LX5VBuild2\Outdir
                    url = r"D:\PyCharm2019\PycharmProjects\pyserver2\shareData"
                    #用来存放所有的文件路径
                    file_list = []
                    #用来存放所有的目录路径
                    dir_list = []
                    #用来存放目录路径
                    dir_lists=[]
                    name=url.split("\\")[-1]
                    tools.get_file_path(url,file_list,dir_list,name,dir_lists)
                    print(file_list)
                    print(dir_list)
                    print(dir_lists)            #共享目录的路径
                    dir=os.listdir(url)
                    for dir in dir_lists:
                        conn.send(b'send_server_dir')
                        time.sleep(0.2)
                        conn.send(bytes(dir.encode('utf-8')))
                        time.sleep(0.2)
                    for i in file_list:
                        conn.send(b'send_server_file')
                        time.sleep(0.3)
                        conn.send(bytes(i.encode('utf-8')))
                        time.sleep(0.2)
                        print(i)
                        with open(i, "rb") as in_file:   #这里修改文件
                            data = in_file.read(1024)
                            while data:
                                conn.send(data)
                                print(f"Sent {data!r}")
                                data = in_file.read(1024)
                        print("Done server_sending")
                        time.sleep(2)
                        conn.send(b'end_server_send')
        except ConnectionResetError:
            continue

3、工具包

import os

import shutil


import sys
import os
import shutil

# find all folders in src_base_dir
# go to one of it
# move files in the folder to dst



# 将目录的文件复制到指定目录
def copy_demo(src_dir, dst_dir):
    """
    复制src_dir目录下的所有内容到dst_dir目录
    :param src_dir: 源文件目录
    :param dst_dir: 目标目录
    :return:
    """
    if not os.path.exists(dst_dir):
        os.makedirs(dst_dir)
    if os.path.exists(src_dir):
        for file in os.listdir(src_dir):
            file_path = os.path.join(src_dir, file)
            dst_path = os.path.join(dst_dir, file)
            if os.path.isfile(os.path.join(src_dir, file)):
                shutil.copyfile(file_path, dst_path)
            else:
                copy_demo(file_path, dst_path)

def CreateDir(path):
    isExists=os.path.exists(path)
    # 判断结果
    if not isExists:
        # 如果不存在则创建目录
        os.makedirs(path)
        print(path+' 目录创建成功')
    else:
        # 如果目录存在则不创建,并提示目录已存在
        print(path+' 目录已存在')


def CopyFile(filepath, newPath):
    # 获取当前路径下的文件名,返回List
    fileNames = os.listdir(filepath)
    for file in fileNames:
        # 将文件命加入到当前文件路径后面
        newDir = filepath + '\\' + file
        # 如果是文件
        if os.path.isfile(newDir):
            print(newDir)
            newFile = newPath + file
            shutil.copyfile(newDir, newFile)
        #如果不是文件,递归这个文件夹的路径
        else:
            CopyFile(newDir,newPath)



def get_file_path(root_path,file_list,dir_list,name,dir_lists):
    #获取该目录下所有的文件名称和目录名称
    dir_or_files = os.listdir(root_path)
    for dir_file in dir_or_files:
        #获取目录或者文件的路径
        dir_file_path = os.path.join(name,dir_file)
        dir_file_paths= os.path.join(name,dir_file)
        #判断该路径为文件还是路径
        if os.path.isdir(dir_file_path):
            dir_list.append(dir_file_path)
            dir_lists.append(dir_file_paths)
            #递归获取所有文件和目录的路径
            get_file_path(dir_file_path,file_list,dir_list,dir_file_paths,dir_lists)
        else:
            file_list.append(dir_file_path)


def str_change(str):
    if not 'bin' in str:
        return str
    else:
        aa, bb = str.split('bin')
        return aa + bb


def func_copy(primary_dir, target_dir):  # 拷贝方法 把原始文件夹的所有文件夹和文件 按照同样的名字拷贝到目标文件夹中
    # 遍历filepath下所有文件,包括目录
    files = os.listdir(primary_dir)
    for i in files:  # i 是目录下的文件或文件夹
        i = os.path.join(primary_dir, i)  # 字符串拼接
        i_new = os.path.join(target_dir, i)  # 目标文件夹也要改变
        if os.path.isdir(i):  # 如果是文件夹
            if not os.path.exists(i_new):  # 如果没新建过 新建同名目标文件夹
                os.makedirs(i_new)
            func_copy(i, i_new)  # 递归循环下一个目录 复制目录里面的内容
        else:  # 不是文件夹 文件 判断字符串是否有_bin 粘贴到指定位置 并且修改名字
            oldname = i
            newname = str_change(i_new)
            print(oldname)
            print(newname)
            if not os.path.exists(newname):  # 如果文件不存在,存在了就不拷贝了
                shutil.copyfile(oldname, newname)


版权声明:本文为hml111666原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。