I have a little problem with my code, I'm doing a HTTP Proxy Server and I send it a random number of HTTP Request and I want that my program close when I stop of send.
I think the problem is in the accept because the program still working always
I tried to put a recv after the accept for checking if there if empty but the program does't arrive there
My code is the following
from socket import *
from _thread import *
MAX_DATA_RECV = 4096 # max number of bytes we receive at once
def start(port_5, my_port):
s=socket(AF_INET, SOCK_STREAM)
s.bind(('', my_port))
s.listen(1)
while 1:
try:
conn, client_addr = s.accept()
except KeyboardInterrupt:
print('\nProgram closed. Interrupted by the user')
exit()
proxy_thread(conn, client_addr)
s.close()
def proxy_thread(conn, client_addr):
# get the request from browser
request = conn.recv(MAX_DATA_RECV).decode('utf-8')
# parse the first line
first_line = request.split('n')[0]
# get url
url = first_line.split(' ')[1]
# find the webserver and port
http_pos = url.find("://") # find pos of ://
if (http_pos==-1):
temp = url
else:
temp = url[(http_pos+3):] # get the rest of url
port_pos = temp.find(":") # find the port pos (if any)
# find end of web server
webserver_pos = temp.find("/")
if webserver_pos == -1:
webserver_pos = len(temp)
webserver = ""
port = -1
if (port_pos==-1 or webserver_pos < port_pos): # default port
port = 80
webserver = temp[:webserver_pos]
else: # specific port
port = int((temp[(port_pos+1):])[:webserver_pos-port_pos-1])
webserver = temp[:port_pos]
print("Connect to:", webserver, port)
# create a socket to connect to the web server
s = socket(AF_INET, SOCK_STREAM)
s.connect((webserver, port))
s.send(request.encode()) # send request to webserver
print(temp)
while 1:
# receive data from web server
data = s.recv(MAX_DATA_RECV)
if (len(data) > 0):
# send to browser
conn.send(data)
else:
break
s.close()
conn.close()
If someone is able to help me, thanks in advance
I want that my program close when I stop of send
At the network level there is no implicit indicator that the other side will not send anymore. If all requests would be done through a single TCP connection then the end of the connection might be treated as such an indicator. But you are using a new TCP connection for every request so you need to define your own condition(s) how the server should determine that the client will not send anymore.
This could for example a timeout, i.e. if the client has not sent any more request for 20 seconds then the client is treated as dead. Or it might be a special message by the client to signal the end - in which case your code needs to explicitly look for this message.
Related
I'm a bit lost in Google-results.
I have a webserver running through a Python built-in module.
This works and provides an area to download automation configuration for devices.
However, I like to build an availability test to provide better code.
If http service is not available, then proceed with tftp server.
I tested with urllib2, but then the website gets timed out. If I try the same code with a named uri 'www.google.com' then the response code 200 is provided.
Any thoughts to provide a good solution?
in the code I provide a ping test.
now like to add 'service-available' test. on TRUE - proceed with GET.
should work on IP-ADDRESS eg.: 10.1.1.1:80
Thank you for the help.
code ex:
import httplib2
h = httplib2.Http(".cache")
(resp_headers, content) = h.request("http://10.10.1.1:80/", "GET")
print(resp_headers)
print(content)
Try this. On a successful ping, the script will attempt to connect to an HTTP service. If the request times out or is not successful (e.g., status 404), it will call your TFTP function:
import shlex
import socket
import subprocess
import httplib2
ip_address = "10.1.1.1"
print("Attempting to ping...")
p = subprocess.Popen(shlex.split("ping -c 3 {0}".format(ip_address)), stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, _ = p.communicate()
rc = p.returncode
if rc != 0 or "100% packet loss" in output.decode():
raise RuntimeError("Unable to connect to {0}.".format(ip_address))
print("Ping successful.")
print("Attempting to connect to an HTTP service....")
h = httplib2.Http(cache=".cache", timeout=10)
response = {}
content = ""
try:
response, content = h.request("http://{0}:80".format(ip_address), method="GET")
if 200 <= int(response["status"]) <= 299:
print("Connected to HTTP service.")
for key, value in response.items():
print(key, ":", value)
print(content.decode())
else:
print("Request not OK. Attempting to connect to a TFTP service...")
# Call to TFTP function goes here
except socket.timeout:
print("Request timed out. Attempting to connect to a TFTP service...")
# Call to TFTP function goes here
Actually, I want to send integers through the server to client and vice versa. So that I can apply some operations on them on the client/server side. But whenever I a try to send integers, the server or client gets automatically destroyed even without sending the message. I have also used a while loop but it's not working as it was supposed to do?
Also, it works fine when I send strings (encoded)
--->server side<----
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print("--------------->SERVER<-----------------")
ip = "127.0.0.1"
port = 8080
s.bind((ip,port))
s.listen(2)
conn,addr = s.accept()
print("CONNECTED WITH THE CLIENT\n")
while True:
#for sending message
temp_msg = input("SERVER - ")
message = int(temp_msg.encode())
conn.send(message)
#for receiving message
rec_msg = conn.recv(1024)
print("CLIENT - ",rec_msg, " type = ", type(rec_msg))
---> client side <----
import socket
print("--------->CLIENT<----------------")
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ip = "127.0.0.1"
port = 8080
s.connect((ip,port))
print("CLIENT1 IS CONNECTED TO THE SERVER")
while True:
#for receiving message
rec_msg = s.recv(1024)
rec_msg = rec_msg
print("SERVER - ", rec_msg," type = ", type(rec_msg))
#for sending message
temp_msg = input("CLIENT - ")
message = int(temp_msg)
s.send(message)
----> output of client side code after sending the initial message through server.py<------
--------->CLIENT<----------------
CLIENT1 IS CONNECTED TO THE SERVER
SERVER - b'' type = <class 'bytes'>
CLIENT -
I found a very simple method to send integer by converting them to string before sending, and then change back to to the integer format after receiving them through a socket.
You can do this by following the below method.
#server side:
num=123
# convert num to str, then encode to utf8 byte
tcpsocket.send(str(num).encode('utf8'))
#client side
data = tcpsocket.recv(1024)
# decode to unicode string
strings = data.decode('utf8')
#get the num
num = int(strings)
here i am making server
my_selector = selectors.DefaultSelector()
keep_running = True
server_address = ('localhost', 1040)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(False)
sock.bind(server_address)
sock.listen(5)
my_selector.register(sock, selectors.EVENT_READ, data=None)
this accept function make new connection
def accept(sock):
# print("Accept Function")
new_connection, addr = sock.accept()
print("Connection established.......")
new_connection.setblocking(False)
my_selector.register(new_connection, selectors.EVENT_READ | selectors.EVENT_WRITE, data=None)
this read function reads data sent by client
def read(connection, mask):
global keep_running
print("Read Function")
if mask & selectors.EVENT_READ:
recv_data = connection.recv(1024)
if recv_data:
print("Message received ", recv_data.decode("utf-8"))
else:
print("Message not received")
my_selector.unregister(connection)
connection.close()
keep_running = False
this loop controls my server
while keep_running:
for key, mask in my_selector.select(timeout=None):
if key.data is None:
accept(key.fileobj)
else:
read(key, mask)
my_selector.close()
my question is when server and client run if server gets a new client it control goes to accept function
or if server gets data it goes to read function this programme shows error
client programme does not show any error client programme only send data
please tell me how to fix this error and i am working on windows 10
Error----OSError: [WinError 10022] An invalid argument was supplied
Try looking at this post maybe it helps you :)
The first answer on that where the guy is having the same error says:
Bind the socket before calling connection.recvfrom(65536) using connection.bind((YOUR_IP, PORT)).
OSError: [WinError 10022] An invalid argument was supplied - Windows 10 Python
In Python, I am trying to build a simple server/client application that sends video bytes to the client.
I have been trying to figure this out for months.
The server is listening to a connection, and is receiving this much data every second, length of 1316
for example:
data = sock_reciever.recv(16000000)
If I print data, I get this:
b'G\x05\x14\x1e\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x1f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x11\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x12\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x13\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x17\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\xff\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
As this comes in, I can send it back out via sock_sender.sendto(data, (SENDMCAST_GRP, SENDMCAST_PORT)), and watch the video in VLC player.
Ultimately, I want to take this data and send it to the client through the socket via conn.send(data).
However, on the client side, I believe data is coming in in the wrong order.
I've compared the data between server and client and it appears to be the same, but it builds up on the client side, which might be causing some sort of overflow.
On the client side, I take the data coming in with data = sock_reciever.recv(16000000) and send it back out via sock_sender.sendto(data, (SENDMCAST_GRP, SENDMCAST_PORT)).
But I do not get the same results on the client side, as on the server side.
How do I add headers to this data to ensure it arrives to the client in sequential order?
If possible, please explain this to me like you would explain what oxygen is to a fish.
Which Sockets I Am Using
I am trying to use TCP sockets between server and client. I thought using a stream socket would be more reliable, but I might be wrong, the only reason being that I would like to do a reverse connection, so that the client connects to the server and then receives data.
I am also using sock_sender.sendto(data, (SENDMCAST_GRP, SENDMCAST_PORT)) just to relay the incoming data on the client side, it is not the actual connection between server and client.
The socket used for the communication between server/client
is called sock_client.
This is the server-side code:
sock_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# recieves connection from client
conn, address = sock_client.accept()
# sends data to client
conn.send(data)
Client Side is set up like so:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
data = s.recv(2400000)
Then the data is just relayed back out for use with other applications via sock_sender.sendto(data, (SENDMCAST_GRP, SENDMCAST_PORT)).
I need to ensure the data between the client/server socket connection is accurate and complete.
Let me explain it a little bit. The video can be sent in the form of bytes with the aid of struct. It is part of the python standard library string services.
It interprets strings as packed binary data and performs conversions between Python values and C structs represented as Python strings. This is helpful handling binary data in files, socket network connections and other sources. In server.py, the frame matrix is pickled dump as a string in variable a and then used struct.pack to add a reference payloadsize (for the string in a). The payload_size is attached using + to the a and then .sendall sends the whole frame. To simply explain it, lets suppose our frame is just 3x3 matrix:
frame=np.array([[1,2,3],[4,5,6],[7,8,9]])
a = pickle.dumps(frame)
The pickled form of frame is shown below as a string:
b'\x80\x03cnumpy.core.multiarray\n_reconstruct\nq\x00cnumpy\nndarray\nq\
x01K\x00\x85q\x02C\x01bq\x03\x87q\x04Rq\x05(K\x01K\x03K\x03\x86q\x06cnumpy
\ndtype\nq\x07X\x02\x00\x00\x00i4q\x08K\x00K\x01\x87q\tRq\n(K\x03X\x01\x00
\x00\x00
Here payload_size: len(a) is 193 and its string representation in a 4 byte 'L' format is b'\xc1\x00\x00\x00'.
Then, message = struct.pack("L", len(a))+a
b'\xc1\x00\x00\x00\x80\x03cnumpy.core.multiarray\n_reconstruct\nq\x00cnumpy\nndarray\nq\
x01K\x00\x85q\x02C\x01bq\x03\x87q\x04Rq\x05(K\x01K\x03K\x03\x86q\x06cnumpy
\ndtype\nq\x07X\x02\x00\x00\x00i4q\x08K\x00K\x01\x87q\tRq\n(K\x03X\x01\x00
\x00\x00
And now the message also contains the payload_size infront of the data. The len(message) = 197.
In client.py the s.recv(4096) means at the most 4096 bytes will be received through a blocking call.
The data is appended to the string in 4096 bytes per packet. The rest of the part is quite obvious.
For reference working versions of server.py and client.py are below. First run the server.py and then in another command window run client.py. The transmitted and received frames will be displayed. You can increase the number of maximum bytes. I hope this solves your problem!
server.py
import socket,cv2,pickle
import struct
serversocket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 9999
serversocket.bind((host, port))
serversocket.listen(5)
while True:
clientsocket,addr = serversocket.accept()
print("Got a connection from %s" % str(addr))
if clientsocket:
vid = cv2.VideoCapture(0)
while(vid.isOpened()):
img, frame = vid.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
print(frame)
a = pickle.dumps(frame)
message =struct.pack("L", len(a))+a
clientsocket.sendall(message)
cv2.imshow('Transmitted',frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
clientsocket.close()
client.py
import socket,cv2,pickle
import struct
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 9999
s.connect((host, port))
data = b""
payload_size = struct.calcsize("L")
while True:
while len(data) < payload_size:
packet= s.recv(4096)
if not packet: break
data += packet
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack("L", packed_msg_size)[0]
while len(data) < msg_size:
data += s.recv(4096)
frame_data = data[:msg_size]
data = data[msg_size:]
frame=pickle.loads(frame_data)
cv2.imshow('Received',frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
s.close()
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\n")
class Recieve(threading.Thread):
def run(self):
while True: # Recieve loop
r_msg = s.recv(buff).decode()
print("\nServer: " + 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.
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\n")
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("\nServer: " + 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.