Search code examples
netcatsocat

socat equivalent of netcat -N


I have a dumb network service that receives an entire file up to EOF and then emits a response.

I can use it like this:

netcat -N $SERVER $PORT < input > output

netcat's -N option causes a shutdown(..., SHUT_WR) to be send when the file is read, so that the server will process and send the output.

I can't find a socat equivalent.

It is something like:

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

but I never manage to get the response data.


Solution

  • Here is a small python server which after discussion minimally mimics the server you describe.

    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))
    

    It correctly returns the hello\n with

    netcat -N $SERVER $PORT < input > output
    

    does not return the hello\n when -N is dropped

    netcat $SERVER $PORT < input > output
    

    but does not work with

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

    socat by default sends the SHUT_WR so shut-down is not needed, the shutdowns are the same for netcat -N and socat. The problem is in the timing. socat works if the time.sleep is excluded so socat is shutting down too quickly. The default delay for socat to shutdown the channel is 0.5 second. This can be extended with the -t option. The following works correctly.

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