Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python sock chat client - Problems with select.select() and sys.stdin

Tags:

python

sockets

So I'm currently trying to make a small chat client using a server and some clients. I found some code online and I wanted to use it as a basis for making my own. The problem I'm facing now is that it was written in Python 2.x and I'm using 3.x. There wasn't really much to convert, but I ran into some problems where the program uses sys.stdin.

The original code can be found here.

Here's my code: `

import sys, socket, select

def chat_client():
    host = 'localhost'
    port = 9009

    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]

        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__":
    chat_client()

`

The error I'm getting is:

`[Me] Traceback (most recent call last):
  File "client.py", line 46, in <module>
    chat_client()
  File "client.py", line 25, in chat_client
    read_sockets, write_sockets, error_sockets = select.select(socket_list , [],
 [])
OSError: [WinError 10038] An operation was attempted on something that is not a
socket`

I'm obviously getting this error because there's no input of any kind, but since I was unable to find any documentation I could understand on what's going on in the lines below, I have a hard time fixing it. I don't know what kind of input it should have gotten through sys.stdin.

`socket_list = [sys.stdin, s]
read_sockets, write_sockets, error_sockets = select.select(socket_list , [], [])`

Sorry If I weren't clear enough on my problem, reply and I'll provide whatever information you need. Thank you for helping me :)

like image 572
TumbaBit Avatar asked Oct 21 '22 04:10

TumbaBit


1 Answers

WinError suggests you're on Windows. sys.stdin can be treated as a socket on *nix platforms but not on Windows.

See: https://docs.python.org/3/library/select.html

Note that on Windows, it only works for sockets; on other operating systems, it also works for other file types (in particular, on Unix, it works on pipes).

A quick search suggests that people might get around this by using select on sockets on one thread and blocking local I/O on a second thread, but don't quote me on that being the best or only way. Async frameworks like Twisted probably have already solved this, as well.

like image 149
Jason S Avatar answered Nov 03 '22 06:11

Jason S