5

I have a TCP server for which I need to write a client in Python.

The server is an arduino using the arduino_uip library; the server code is (almost) the same as the TCP server example of that library. It works fine using nc as a client.

But when I use python sockets (as in this answer) to communicate with the server, the server hangs on socket shutdown or close.

That may be an issue with the server; however since nc is working fine as a client, my question is :

What does this answer do differently from nc that may explain server hanging on connection shutdown/close)?

Summing up what works & what not :

  • python client & nc -l as server: works
  • nc as client & arduino server : works
  • python client & arduino server: hangs server

Here is the client code :

import socket
    
def netcat(hostname, port, content):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((hostname, port))
    s.sendall(content)
    s.shutdown(socket.SHUT_WR)
    while 1:
        data = s.recv(1024)
        if data == b"":
            break
        print("Received:", repr(data))
    print("Connection closed.")
    s.close()

Edit :

It appears (Vorsprung's answer made me think about it!)that it is in fact a timing problem. If I add sleep(0.5) before shutdown in the above code all works nicely (as in netcat where there is a manual delay before I hit Ctrl+C). I suppose I'll have to check that arduino library now...

scls
  • 16,591
  • 10
  • 44
  • 55
Nicolas D
  • 236
  • 1
  • 3
  • 6
  • 1
    Did you try removing the `s.shutdown()` call? You say it hangs on `socketshutdown or close` - do you mean both/either? – Gerrat Nov 06 '13 at 18:22

2 Answers2

2

Had a look at the netcat source ( svn checkout svn://svn.code.sf.net/p/netcat/code/trunk netcat-code ) and it only calls shutdown() just before it closes, not just after setting up the socket

That's the difference as far as I can see

Vorsprung
  • 32,923
  • 5
  • 39
  • 63
  • Thanks for that answer! It led me to the path to the difference (which was in timing, stupid me...). I edited the question to reflect that. – Nicolas D Nov 07 '13 at 12:42
0

python equivalent of netcat

Use nclib: pip install nclib

Documentation: https://nclib.readthedocs.io/en/latest/

Python 3 netcat listener, input and output assigned to variables command and data respectively.

import nclib


def listener(port):
    """ local netcat listener for reverse bash shell from a remote host. """
    server = nclib.TCPServer(('0.0.0.0', int(port)))
    print("listening ...")
    for client in server:
        print('Connected to %s:%d' % client.peer)
        command = ""
        while command != "exit":
            try:
                # if command was entered by the user
                if len(command) > 0:
                    # read the line to hide command from output
                    if command in client.readln().decode('utf-8').strip(" "):
                        pass  # disregard the last command

                # get output until dollar sign (bash --posix forces bash-X.X$)
                data = client.read_until('$')
                print(data.decode('utf-8'), end="")  # print string of received bytes

                # get user input command and write command to socket
                command = input(" ")
                client.writeln(command)

            # handle exceptions and exiting
            except KeyboardInterrupt:
                print("\nKeyboardInterrupt")
                exit(1)
            except Exception as e:
                print("\nException Occurred\n")
                print(e)
                exit(1)
        print("Disconnected :-)")
        exit(1)