передача файлов сокета python3

задняя часть сервер Nginx Tomcat

Сцены:

Система CMS была развернута с использованием архитектуры Nginx и Tomcat, то есть статические файлы были размещены на сервере, развернутом Nginx, а фоновый динамический код (класс системы управления фоном cms) был развернут на другом сервере Tomcat. Система, развернутая Tomcat, файлы статических страниц (файлы HTML и т. д.), сгенерированные после публикации статьи, необходимо скопировать на сервер Nginx (лучшее решение — совместное хранение двух серверов). Требовать:

  1. Статические файлы, сгенерированные службой Tomcat, синхронизируются со службой Tomcat в режиме реального времени (с интервалом в 5 минут).
  2. Автоматический мониторинг, работа 7*24
  3. Объект удобен в развертывании

Решения:

  1. Используйте разработку python3, удобную и быструю, основной сервер - версия Linux
  2. Корневая папка, которую необходимо синхронизировать в службе Tomcat, пока происходит изменение файла (добавление, изменение, удаление), она инициирует синхронизацию.

Встречаются проблемы:

  1. Как клиент отслеживает изменения файла в режиме реального времени
  2. При создании файла мониторинг обнаружил, что метод модификации файла срабатывал дважды
  3. Когда содержимое файла большой, доставка сокета запускается до завершения копии, что делает неудачу файла передачи (потому что файл не был изменен)
  4. Циклическое ожидание может быть реализовано как на стороне сервера, так и на стороне клиента.

решение:

  1. Изменения файлов мониторинга на стороне клиента основаны на разных системах и используют разные подключаемые модули. Использование файла win32 в Windows
  2. Установите размер файла, который может быть доставлен
  3. Установите время ожидания, то есть подождите, пока файл будет создан или изменен, прежде чем сокет может быть доставлен.
  4. На стороне сервера: получить имя файла, создать файл, сохранить файл, продолжить ожидание.

Код

код клиента

#!/user/bin/python
# -*- coding: utf-8 -*-
'''
python3 socket 文件传输----客户端(Windows版本):
v1.5:
1、监控指定文件夹变化
2、瓶颈在文件大小:即写文件时间,如果读取文件时,文件没有写入完成,就会报错。
    解决方法:添加等待时间time.sleep(3)#等待3秒
'''
import socket, os,time,logging
import zipfile
import sys
import win32file
import win32con

socket = socket.socket()
socket.connect(("127.0.0.1", 9999))
SIZE = 1024 * 1024 * 2000

print(socket.recv(SIZE))
print("sending please wait for a second....")

ACTIONS = {
    1: "Created",
    2: "Deleted",
    3: "Updated",
    4: "Renamed from something",
    5: "Renamed to something"
}
FILE_LIST_DIRECTORY = 0x0001

path_to_watch = 'E:\\temp'
print('Watching changes in', path_to_watch)
hDir = win32file.CreateFile(
    path_to_watch,
    FILE_LIST_DIRECTORY,
    win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
    None,
    win32con.OPEN_EXISTING,
    win32con.FILE_FLAG_BACKUP_SEMANTICS,
    None
)

COUNT = 0

while 1:
    results = win32file.ReadDirectoryChangesW(
        hDir,
        1024,
        True,
        win32con.FILE_NOTIFY_CHANGE_FILE_NAME |
        win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
        win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
        win32con.FILE_NOTIFY_CHANGE_SIZE |
        win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |
        win32con.FILE_NOTIFY_CHANGE_SECURITY,
        None,
        None)
    COUNT = COUNT + 1
    print(results)
    print(COUNT)
    print("--------")
    for action, filename in results:
        full_filename = os.path.join(path_to_watch, filename)
        print(full_filename, ACTIONS.get(action, "Unknown"))
        if action == 3:
            print("permission =======")
            print(full_filename)
            time.sleep(3) #睡眠时间:等待文件复制完成
            try:
                f2 = open(full_filename, 'rb')
                socket.sendall(bytes(f2.name, encoding="utf-8"))
                data = f2.read(SIZE)
                socket.sendall(data)
                f2.close()
            except Exception as e:
                logging.error("文件打开异常...")
                logging.exception(e)
            finally:
                pass

print("sended!")
socket.close()
print("connection closed")


код сервера

#!/user/bin/python
# -*- coding: utf-8 -*-
'''
python3 socket 文件传输--服务端(Windows版本):
v1.5:
1、接收客户端传递过来的文件

'''
import socket, os,logging
from datetime import datetime

socket = socket.socket()
socket.bind(("127.0.0.1", 9999))
socket.listen(20)
SIZE = 1024*1024*2000
savepath = "D:\\workspace\\python\\demo\\sc1\\py_s\\ss"

def Service():
    while True:
        conn, addr = socket.accept()
        print('Accept new connection from %s:%s...' % addr)
        conn.sendall(bytes("Welcome from server!", encoding="utf-8"))
        print(conn)
        try:
            while True:
                fpath = str(conn.recv(1024), encoding="utf-8")
                f_dir = os.path.split(fpath)[0]
                fname = os.path.split(fpath)[1]
                fnameSave = os.path.join(savepath,fname)
                if not os.path.isdir(savepath):
                    os.makedirs(savepath)
                ff = open(fnameSave, 'wb') # 按照配置的路径进行存储
                starttime = datetime.now()
                print("start...")
                recvdata = conn.recv(SIZE)
                if not recvdata:
                    print("reach the end of file")
                    break
                else:
                    ff.write(recvdata)
                ff.close()
                endtime = datetime.now()
                print("end...花费时间(s)",(endtime-starttime).seconds)
        except Exception as e:
            logging.error("服务器异常...")
            logging.exception(e)
        finally:
            conn.close()

    print("receive finished")
    print("connection from %s:%s closed." % addr)

if __name__ == '__main__':
    Service()


Суммировать

  • Операции с файлами связаны с операционной системой, и базовые библиотеки разных системных вызовов различны.
  • Сейчас реализована только виндовая версия, и тестируется она только в системе win10
  • Передача одного файла имеет ограничение по размеру
  • При отслеживании изменений файла конфликтует со временем изменения и записи файла.Когда сокет инициирует передачу, операция с файлом должна быть закрыта, иначе будет сообщено об ошибке.
  • Дальнейшие планы:
    • Реализовать версию для Linux
    • Реализовать доставку пакетов
    • Реализовать передачу больших файлов