1

In an attempt to get a chat system working in Python using Windows, I have used the following code on the client-side:

chat_client.py

import sys, socket, select

def chat_client():
    if(len(sys.argv) < 3) :
        print 'Usage : python chat_client.py hostname port'
        sys.exit()

    host = sys.argv[1]
    port = int(sys.argv[2])

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(2)

    # connect to remote host
    try :
        s.connect((host, port))
    except :
        print 'Unable to connect'
        sys.exit()

    print 'Connected to remote host. You can start sending messages'
    sys.stdout.write('[Me] '); sys.stdout.flush()

    while 1:
        socket_list = [sys.stdin, s]

        # Get the list sockets which are readable
        read_sockets, write_sockets, error_sockets = select.select(socket_list , [], [])

        for sock in read_sockets:            
            if sock == s:
                # incoming message from remote server, s
                data = sock.recv(4096)
                if not data :
                    print '\nDisconnected from chat server'
                    sys.exit()
                else :
                    #print data
                    sys.stdout.write(data)
                    sys.stdout.write('[Me] '); sys.stdout.flush()     

            else :
                # user entered a message
                msg = sys.stdin.readline()
                s.send(msg)
                sys.stdout.write('[Me] '); sys.stdout.flush() 

if __name__ == "__main__":

    sys.exit(chat_client())

However, I am getting the following error when attempting to connect to a server (which is running in Python too):

select.error: (10038, 'An operation was attempted on something that is not a socket')

This has something to do with sys.stdin.

I believe this is issue with file objects on Windows not being acceptable, but sockets are. On Windows, the underlying select function is provided by the WinSock library, and does not handle file descriptors that don’t originate from WinSock.

Is there a workaround to this to allow for a way to implement the chat_client.py code on Windows?

4
  • ...don't try to use stdin as if it were a socket? Not sure what kind of answer you're expecting here. Commented Jan 30, 2017 at 17:42
  • Lots of ways to implement the "don't do that" approach. One is multithreading -- if you have a separate thread reading from stdin, it can do the easy thing and use a blocking read call, while your network code uses select() and recv() (the latter of which is likewise a socket call not expected to work with stdin). Commented Jan 30, 2017 at 17:43
  • Plenty of existing questions this overlaps. See for example stackoverflow.com/questions/10842428/… and stackoverflow.com/questions/12499523/… Commented Jan 30, 2017 at 17:44
  • Thanks for your comments Charles. I'm attempting to follow this guide to making the chat application: bogotobogo.com/python/… I used multithreading before, and I've had a look at the questions you've listed however I wasn't able to get a definitive solution. Commented Jan 30, 2017 at 17:50

1 Answer 1

1

Is there a workaround to this to allow for a way to implement the chat_client.py code on Windows?

You could manage with periodical checking of input activity, e. g. by replacing your select statement with

        # Get the list sockets which are readable, time-out after 1 s
        read_sockets = select.select([s], [], [], 1)[0]
        import msvcrt
        if msvcrt.kbhit(): read_sockets.append(sys.stdin)

Note that in this example approach, when one began typing in a line, incoming messages will only be displayed after the input line is finished.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.