эквивалент socat для netcat -N

У меня есть глупая сетевая служба, которая получает весь файл до EOF, а затем отправляет ответ.

Я могу использовать это так:

netcat -N $SERVER $PORT < input > output

Опция netcat -N вызывает отправку shutdown(..., SHUT_WR) при чтении файла, чтобы сервер обработал и отправил вывод.

Я не могу найти эквивалент socat.

Это что-то вроде:

socat - TCP:$SERVER:$PORT,linger=5000,shut-down < input > output

но мне никогда не удается получить данные ответа.


person Sam Liddicott    schedule 02.08.2019    source источник


Ответы (1)


Вот небольшой сервер Python, который после обсуждения минимально имитирует сервер, который вы описываете.

import asyncio
import time

class FileReceiver(asyncio.Protocol):

    def connection_made(self, transport):
        print("connection_made")
        self.transport = transport

    def data_received(self, data):
        print(data)

    def eof_received(self):
        time.sleep(2)
        self.transport.write("hello\n".encode());
        if self.transport.can_write_eof():
            self.transport.write_eof()
        return True    

async def main(host, port):
    loop = asyncio.get_event_loop()
    server = await loop.create_server(FileReceiver, host, port)
    await server.serve_forever()

asyncio.run(main('127.0.0.1', 5000))

Он правильно возвращает привет\n с

netcat -N $SERVER $PORT < input > output

не возвращает приветствие\n при удалении -N

netcat $SERVER $PORT < input > output

но не работает с

socat - TCP:$SERVER:$PORT < input > output

socat по умолчанию отправляет SHUT_WR, поэтому выключение не требуется, выключения одинаковы для netcat -N и socat. Проблема в сроках. socat работает, если time.sleep исключен, поэтому socat отключается слишком быстро. Задержка по умолчанию для socat, чтобы закрыть канал, составляет 0,5 секунды. Это можно расширить с помощью опции -t. Следующее работает корректно.

socat -t 5 - TCP:$SERVER:$PORT < input > output
person Bill    schedule 03.08.2019
comment
Я очень благодарен за неприятности, на которые вы пошли. После добавления в ваш пример (после print("eof") строки self.transport.write("hello\n".encode()); я обнаружил, что пример socat действительно сбрасывает вывод hello, но если я также сначала добавлю строку time.sleep(2) (за которой следует transport.write), тогда я нахожу что socat не выводит привет, а netcat -N выводит (версия socat 1.7.3.2). socat закрывает соединение раньше, вызывая ошибки на вашем сервере python, которые не вызывает netcat. я не могу найти способ остановить это. - person Sam Liddicott; 05.08.2019
comment
Ах, это помогает. поэтому вам нужна более длительная задержка, прежде чем он выключится. Это опция -t для socat. - person Bill; 05.08.2019
comment
Я отредактировал ответ, чтобы отразить обсуждение. - person Bill; 05.08.2019
comment
спасибо - это то, что мне было нужно. Кажется, что -t - это тайм-аут простоя, который не разъясняется на странице руководства. Когда один канал достигает EOF, часть записи другого канала отключается. Затем socat ждет ‹timeout› [timeval] секунд перед завершением. вероятно, следует ждать ‹timeout› [timeval] секунд бездействия перед завершением. Я обнаружил, что, пока t достаточно велико, не имеет значения, сколько времени занимает ответ, пока он делает прогресс по сравнению с -t ценность. Отличный ответ, спасибо. - person Sam Liddicott; 06.08.2019