Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
921 views
in Technique[技术] by (71.8m points)

multithreading - Simultaneous input and output for network based messaging program

In python, I am creating a message system where a client and server can send messages back and forth simeltaneously. Here is my code for the client:

import threading
import socket

# Global variables
host = input("Server: ")
port = 9000
buff = 1024

# Create socket instance
s = socket.socket()

# Connect to server
s.connect( (host, port) )
print("Connected to server
")


class Recieve(threading.Thread):
    def run(self):
        while True: # Recieve loop
            r_msg = s.recv(buff).decode()
            print("
Server: " + r_msg)

recieve_thread = Recieve()
recieve_thread.start()

while True: # Send loop
    s_msg = input("Send message: ")

    if s_msg.lower() == 'q': # Quit option
        break

    s.send( s_msg.encode() )

s.close()

I have a thread in the background to check for server messages and a looping input to send messages to the server. The problem arises when the server sends a message and the user input is immediately bounced up to make room for the servers message. I want it so that the input stays pinned to the bottom of the shell window, while the output is printed from the 2nd line up, leaving the first line alone. I have been told that you can use curses or Queues to do this, but I am not sure which one would be best in my situation nor how to implement these modules into my project.

Any help would be appreciated. Thank you.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I want it so that the input stays pinned to the bottom of the shell window, while the output is printed from the 2nd line up, leaving the first line alone. I have been told that you can use curses

Here's a supplemented version of your client code using curses.

import threading
import socket

# Global variables
host = input("Server: ")
port = 9000
buff = 1024

# Create socket instance
s = socket.socket()

# Connect to server
s.connect( (host, port) )
print("Connected to server
")

import sys
write = sys.stdout.buffer.raw.write
from curses import *
setupterm()
lines = tigetnum('lines')
change_scroll_region = tigetstr('csr')
cursor_up            = tigetstr('cuu1')
restore_cursor       = tigetstr('rc')
save_cursor          = tigetstr('sc')

def pin(input_lines):   # protect input_lines at the bottom from scrolling
        write(save_cursor + 
              tparm(change_scroll_region, 0, lines-1-input_lines) + 
              restore_cursor)

pin(1)

class Recieve(threading.Thread):
    def run(self):
        while True: # Recieve loop
            r_msg = s.recv(buff).decode()
            write(save_cursor+cursor_up)
            print("
Server: " + r_msg)
            write(restore_cursor)

recieve_thread = Recieve()
recieve_thread.daemon = True
recieve_thread.start()

while True: # Send loop
    s_msg = input("Send message: ")

    if s_msg.lower() == 'q': # Quit option
        break

    s.send( s_msg.encode() )

pin(0)
s.close()

It changes the scrolling region to leave out the screen's bottom line, enters the scrolling region temporarily to output the server messages, and changes it back at the end.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...