One way to implement a TCP server in Python is to inherit from the socketserver module. We subclass BaseRequestHandler and then override the inherited handle method. In very few lines of Python code, we can implement a TCP server:
from socketserver import BaseRequestHandler, TCPServer
class RequestHandler(BaseRequestHandler):
# override base class handle method
def handle(self):
print('Server connected to: ', self.client_address)
while True:
rsp = self.request.recv(512)
if not rsp: break
self.request.send(b'Server received: ' + rsp)
def start_server():
server = TCPServer(('', 24000), RequestHandler)
server.serve_forever()
We are passing in our RequestHandler class into a TCPServer initializer. The empty single quotes are a short cut for passing in localhost, which is our own PC. This is the IP address of 127.0.0.1. The second item in the tuple is the port number. We can choose any port number that is not in use on our local PC.
We just have to make sure that we are using the same port on the client side of the TCP connection; otherwise, we would not be able to connect to the server. Of course, we have to start the server first before clients can connect to it.
We will modify our Queues.py module to become the TCP client:
# using TCP/IP
from socket import socket, AF_INET, SOCK_STREAM
def write_to_scrol(inst):
print('hi from Queue', inst)
sock = socket(AF_INET, SOCK_STREAM)
sock.connect(('localhost', 24000))
for idx in range(10):
sock.send(b'Message from a queue: ' +
bytes(str(idx).encode()) )
recv = sock.recv(8192).decode()
inst.gui_queue.put(recv)
inst.create_thread(6)
When we now click the Click Me! button, we are calling bq.write_to_scrol(self), which then creates the socket and connection shown precedingly.
This is all the code we need to talk to the TCP server. In this example, we are simply sending some bytes to the server and the server sends them back, prepending some strings before returning the response.
Once we know how to connect to a remote server via TCP/IP, we will use whatever commands are designed by the protocol of the program we are interested in communicating with. The first step is to connect before we can send commands to specific applications residing on a server.
In the writeToScrol function, we will use the same loop as before, but now we will send the messages to the TCP server. The server modifies the received message and then sends it back to us. Next we place it into the GUI member queue, which, as in the previous recipes, runs in its own thread:
sock.send(b'Message from a queue: ' + bytes(str(idx).encode()) )
Note the b before the string and then, well, all the rest of the required casting.
We start the TCP server in its own thread in the initializer of the OOP class:
class OOP():
def __init__(self):
# Start TCP/IP server in its own thread
svrT = Thread(target=startServer, daemon=True)
svrT.start()
Clicking the Click Me! button on Tab 1 now creates the following output in our ScrolledText widget as well as on the console, and the response due to the use of threads is very fast:
GUI_TCP_IP.py