Last active
March 11, 2021 12:21
-
-
Save kuntalchandra/38656a8242273edb69c39f40eb20f210 to your computer and use it in GitHub Desktop.
Python socket programming: server-client design.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket | |
import sys | |
def main(): | |
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
host = "127.0.0.1" | |
port = 8888 | |
try: | |
soc.connect((host, port)) | |
except: | |
print("Connection error") | |
sys.exit() | |
print("Enter 'quit' to exit") | |
message = input(" -> ") | |
while message != 'quit': | |
soc.sendall(message.encode("utf8")) | |
if soc.recv(5120).decode("utf8") == "-": | |
pass # null operation | |
message = input(" -> ") | |
soc.send(b'--quit--') | |
if __name__ == "__main__": | |
main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket | |
import sys | |
import traceback | |
from threading import Thread | |
def main(): | |
start_server() | |
def start_server(): | |
host = "127.0.0.1" | |
port = 8888 # arbitrary non-privileged port | |
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # SO_REUSEADDR flag tells the kernel to reuse a local socket in TIME_WAIT state, without waiting for its natural timeout to expire | |
print("Socket created") | |
try: | |
soc.bind((host, port)) | |
except: | |
print("Bind failed. Error : " + str(sys.exc_info())) | |
sys.exit() | |
soc.listen(5) # queue up to 5 requests | |
print("Socket now listening") | |
# infinite loop- do not reset for every requests | |
while True: | |
connection, address = soc.accept() | |
ip, port = str(address[0]), str(address[1]) | |
print("Connected with " + ip + ":" + port) | |
try: | |
Thread(target=client_thread, args=(connection, ip, port)).start() | |
except: | |
print("Thread did not start.") | |
traceback.print_exc() | |
soc.close() | |
def client_thread(connection, ip, port, max_buffer_size = 5120): | |
is_active = True | |
while is_active: | |
client_input = receive_input(connection, max_buffer_size) | |
if "--QUIT--" in client_input: | |
print("Client is requesting to quit") | |
connection.close() | |
print("Connection " + ip + ":" + port + " closed") | |
is_active = False | |
else: | |
print("Processed result: {}".format(client_input)) | |
connection.sendall("-".encode("utf8")) | |
def receive_input(connection, max_buffer_size): | |
client_input = connection.recv(max_buffer_size) | |
client_input_size = sys.getsizeof(client_input) | |
if client_input_size > max_buffer_size: | |
print("The input size is greater than expected {}".format(client_input_size)) | |
decoded_input = client_input.decode("utf8").rstrip() # decode and strip end of line | |
result = process_input(decoded_input) | |
return result | |
def process_input(input_str): | |
print("Processing the input received from client") | |
return "Hello " + str(input_str).upper() | |
if __name__ == "__main__": | |
main() |
Thread
is Python's in-built library class, refer to the import statement from threading import Thread
. It's opening a thread from the Try
block to start the communication with the client.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, thanks for the upload!
After going through your code, I noticed on line 35, "Thread(target=client_thread, args=(connection, ip, port)).start()"
you set target variable to = client_thread, however, I cant see any reference to client_thread in your code, what exactly is happening here? Could you please explain!
Thank you