IsolatedSushi
IsolatedSushi

Reputation: 23

Python how to stop the interference of a print and input in cmd?

I'm trying to make a chat between 2 computers with python, nothing fancy just using command prompt lines.

Now the code on the servers side looks like this:

import socket
import threading
import time

def socket_create():
    try:
        global host
        global port
        global s
        host = #Some IP
        port = 9998
        s = socket.socket()
    except socket.error as msg:
        print(msg)

def socket_bind():
    try:
        global port
        global host
        global s
        print("Binding socket to port: " + str(port))
        s.bind((host ,port))
        s.listen(4)
    except socket.error as msg:
        print(msg)
        socket_bind

def socket_accept():
    global conn
    conn, address = s.accept()
    print("Connection with" + address[0] + str(address[1]))
    t1 = threading.Thread(target = receive_message)
    t2 = threading.Thread(target = send_message)
    t1.daemon = True
    t2.daemon= True
    t1.start()
    t2.start()


def send_message():
    global conn
    time.sleep(1)
    while True:
        print(2)
        send_msg = input("You>")
        if send_msg != b'':
            conn.send(str.encode(send_msg))
            print("msg sent")

def receive_message():
    global conn
    time.sleep(0.5)
    while True:
        receive_msg = conn.recv(2048)
        print("Him>" + receive_msg.decode())


def main():

    global conn
    socket_create()
    socket_bind()
    socket_accept()




main()

while the code on the clients side looks like this:

import threading
import socket
import time

s = socket.socket()
host = #SomeIP
port = 22222
s.connect((host,port))


def receive_message():
    time.sleep(0.5)
    while True:

        print(1)
        msg = s.recv(1024)
        print(3)
        print(msg.decode())

def send_message():
    time.sleep(1)
    while True:

        print(2)
        message = input()
        s.send(str.encode(message))



t1 = threading.Thread(target = receive_message)
t2 = threading.Thread(target = send_message)
t1.daemon = True
t2.daemon = True
t1.start()
t2.start()

Now the issue I'm having is that when a person is typing, and receives a message from the other side it writes it on the input.

For example, when I'm busy typing "Hey have you finis" and receive a message like "Hey", it looks like this "Hey have you finisHey".

I've tried printing it on a new line with '\n' but that doesnt work either because then I have to start typing all over again.

Anyone have any ideas?

Cheers.

Upvotes: 1

Views: 355

Answers (1)

Lawrence Kok
Lawrence Kok

Reputation: 1598

This is not really trivial to solve. In normal circumstances the simplest answer would be to place a 'lock' (multi-threading primitive) around the regions that you want to have exclusive usage. For example you could put a lock around the places where you print, and a lock around the places where you request input.

In your case this probably will work to some extend, it should make the 'receiving' messages stop from being printed until after you type something. For the recipient he/she needs to type something before they see the messages, so at the same time not entirely desired behavior.

The problem with the input call is that it is blocking all the way until somebody hits enter. So for your program it's also not able to detect, if you are writing a message or if it is safe to print something. You could solve that maybe that by reading the keyboard directly.

On that note it's probably just easier to actually do this with a user-interface: have one textbox for receiving texts, one textbox for sending text. Trying to solve this in a command-line program is probably going to give you a unnecessary hard-time.

Upvotes: 1

Related Questions