2

So I'm learning about socket programming and have wrote a nifty little chat server. The problem I am having is that my client cannot read and write at the same time. I'm not too sure how to set this up.

This is what I have so far, I want read() and write() to be running concurrently (It isn't so much about reading and writing at the same time - it's about being able to receive messages while input() hangs waiting for user input.):

import socket 
import threading

class Client(threading.Thread):

    def __init__(self):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.connect(('127.0.0.1', 1234))
        print('Client connected to server')

        self.readThread = threading.Thread.__init__(self)
        self.writeThread = threading.Thread.__init__(self)

    def read(self):
        data = self.socket.recv(1024)
        if data:
            print('Received:', data)

    def write(self):
        message = input()
        self.socket.send(bytes(message, 'utf-8'))


client = Client()

while True:
    #do both
3
  • You're going to want to create two separate threading objects for reading and writeing. If your socket implementation is not threadsafe, You'll have to add either a locking primitive, or maybe a system that enqueues read and write requests to the socket. Or you could just use two sockets, one for reading and one for writing. Commented Jul 28, 2012 at 2:55
  • Thanks for replying. It isn't so much about reading and writing at the same time - it's about being able to receive messages while input() hangs waiting for user input. Thoughts? Commented Jul 28, 2012 at 3:25
  • 1
    From the docs, it appears socket has a non-blocking mode. Threading may be unnecessary. Commented Jul 28, 2012 at 3:40

1 Answer 1

3

You're really close. Try something like this:

import socket 
import threading

class Client(threading.Thread):

    def __init__(self):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.connect(('127.0.0.1', 1234))
        print('Client connected to server')

        t = threading.Thread(target = self.read)
        t.daemon = True # helpful if you want it to die automatically
        t.start()

        t2 = threading.thread(target = self.write)
        t2.daemon = True
        t2.start()

    def read(self):
        while True:
            data = self.socket.recv(1024)
            if data:
                print('Received:', data)

    def write(self):
        while True:
            message = input()
            self.socket.send(bytes(message, 'utf-8'))


client = Client()

It's worth pointing out that if you're reading and writing from a single terminal this way your prompt could get a little out of hand. I imagine though that you're starting with print statements, but will eventually collect data into other containers in your app.

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

1 Comment

Thanks! It was only running read() and write() once with daemon = True, but without it works!

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.