2

I'm trying to create a simple python chat interface however when two clients are connected to the server, the first clients console prints blank spaces as quick as possible and causes a max recursion depth error while the second client still works fine. The server code only sends data when its not blank so i'm not sure why it does this.

Server code:

import socket
from threading import Thread
from socketserver import ThreadingMixIn

class ClientThread(Thread):

    def __init__(self,ip,port):
        Thread.__init__(self)
        self.ip = ip
        self.port = port
        print("[+] New thread started for "+ip+": "+str(port))

    def run(self):
        while True:
            data = conn.recv(1024).decode()
            if not data: break
            if data == "/exit":
                print("Connection for "+ip+" closed.")
                data = "Connection closed."
                conn.send(data.encode())
                break
            else:
                print("received data: ", data)
            if data != " ":
                conn.send(data.encode())
        print("connection "+ip+" force closed.")

TCP_IP = socket.gethostname()
TCP_PORT = 994
BUFFER_SIZE = 1024

tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.bind((TCP_IP, TCP_PORT))
threads = []

while True:
    tcpsock.listen(4)
    (conn, (ip,port)) = tcpsock.accept()
    newthread = ClientThread(ip,port)
    newthread.start()
    threads.append(newthread)

for t in threads:
    t.join()

Client code:

import socket
import threading
from threading import Thread

TCP_IP = socket.gethostname()
TCP_PORT = 994
BUFFER_SIZE = 1024

name = str(input("Input username: "))

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))

def recv():
    while True:
        data = s.recv(BUFFER_SIZE).decode()
        if not data: break
        print(data)
    recv()

def send():
    message = str(input())
    if message != "/exit":
        message = name + ": " + message
    s.send(message.encode())
    send()

if __name__ == "__main__":
    Thread(target = recv).start()
    Thread(target = send).start()

The error is at line 19 in the client code (where its receiving and printing any data sent by the server) Any help would be greatly appreciated.

Thomas288
  • 21
  • 4

1 Answers1

0

The most probable reason is the recursion in your send and receive routines, I changed them to be loops instead.

def recv():
    while True:
        data = s.recv(BUFFER_SIZE).decode()
        if not data: break
        print(data)

def send():
    while True:
        message = str(input())
        if message != "/exit":
            message = name + ": " + message
        s.send(message.encode())

A solution to shutting down these threads is given here: Is there any way to kill a Thread in Python?

But it is not necessary to run send and receive in single threads in this scenario in the clients.

EDIT: I read again carefully your code. In the client you start the send and receive method as threads. The send thread does not get any input for its message string in the thread and because you loop it, it sends empty messages to the server or (in my case) exits with an error.

Dschoni
  • 3,714
  • 6
  • 45
  • 80
  • The input is at "message = str(input())". It waits for the user to put an input which is why I made multiple threads. How would I do this without multiple threads? In one thread it wont post new messages until the user sends a message. I might be misunderstanding you though because I haven't programmed python in quite a while and i'm also new to networking and threads in python. – Thomas288 Feb 09 '18 at 12:35
  • now I get it, you want the full chat to be visible in every input field instantly, right? – Dschoni Feb 09 '18 at 12:39
  • yea, even if the user isn't sending anything I want their chat log to update. – Thomas288 Feb 09 '18 at 12:40
  • I might be wrong on this, but every thread sees its own connection. You can write to this connection by the thread only. To be able to write to other threads, the server's main thread has to communicate with the threads for each connection. You can use a queue to do this. – Dschoni Feb 09 '18 at 13:43
  • Here is a good example for a polling solution without threading and queues: http://www.bogotobogo.com/python/python_network_programming_tcp_server_client_chat_server_chat_client_select.php – Dschoni Feb 09 '18 at 14:05