О файловом вводе / выводе с использованием сокета в python - PullRequest
0 голосов
/ 25 мая 2018

У меня были проблемы с кодированием программы ввода / вывода файлов с использованием сокета в python.Цель моей серверной программы - отправить текстовый файл клиентской программе через сокет.Хотя я подтвердил, что клиентская программа получает некоторые данные от серверной программы, клиент не может записать данные в файл.В чем проблема???Пожалуйста, помогите мне ..

[server.py]

import socketserver
from time import sleep

class TCPSocketHandler(socketserver.BaseRequestHandler):
    def handle(self):
        sock = self.request
        while True:
            with open('imageNames.txt', 'r') as file:
                try:
                    names=file.readlines()
                    for name in names:
                        print(name)
                        sock.send((name.encode('utf-8')))
                except Exception as exc:
                    print(exc)
            sleep(60)

def main():
    HOST, PORT = "192.168.xx.xx", 7799
    server = socketserver.TCPServer((HOST, PORT), TCPSocketHandler)
    server.serve_forever()

if __name__ == '__main__':
    main()

[client.py]

import socket

def main():
    HOST, PORT = "192.168.xx.xx", 7799
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        sock.connect((HOST, PORT))
        data = (sock.recv(1024)).decode('utf-8')
        with open('imageNames2.txt', 'w') as file:
            try:
                while data:
                    print(data)
                    file.write(data)
                    data = (sock.recv(1024)).decode('utf-8')
            except Exception as e:
                print(e)

if __name__ == '__main__':
    main()

1 Ответ

0 голосов
/ 25 мая 2018

Большое редактирование

После еще нескольких копаний я обнаружил, что то, что я писал ранее, было только частично правильным.Настоящей причиной является буферизация, как в Python, так и на уровне файловой системы.

Если создан объект TextIO, существует буфер, который накапливает вводные данные, чтобы избежать чрезмерных системных вызовов.Как только этот буфер заполнится, содержимое будет сброшено в файловую систему, где он может оказаться в другом буфере, пока этот буфер не заполнится и содержимое, наконец, не будет записано в файл.Теперь выходящий из него менеджер контента, то есть внутренний вызов close () в TextIO, неявно принудительно очищает буферы.

Когда цикл на сервере спит 60 секунд, возможно, и вы, и я недостаточно терпеливыждать, пока буферы не заполнятся до уровня, который вызывает сброс для просмотра содержимого файла на диске.

Если вы хотите, чтобы каждый блок, который получает клиент, немедленно отображался в файле, вы 'Вам придется явно очистить буфер TextIO и вызвать os.fsync (), чтобы также запустить очистку буфера файловой системы.

Итак, вот как вы можете изменить клиента, сохраняя при этом сервер в его бесконечном циклесодержимое файла:

import os
import socket


def main():
    HOST, PORT = "127.0.0.1", 7799
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        sock.connect((HOST, PORT))
        data = (sock.recv(1024)).decode('utf-8')
        with open('imageNames2.txt', 'w') as file:
            try:
                while data:
                    file.write(data)
                    file.flush()
                    os.fsync(file.fileno())
                    print(data)
                    data = (sock.recv(1024)).decode('utf-8')
            except Exception as e:
                print(e)

if __name__ == '__main__':
    main()

Обратите внимание, что в некоторых средах разработки, таких как PyCharm, новый файл может не отображаться в обзоре проекта, пока файл не будет закрыт.На уровне файловой системы, однако, он существует.

Кроме того, мое предыдущее замечание о потере первой строки было неверным.Извините за это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...