Question: Asking for advice here. So I have a business that sells a specific kind of routers. One of the features is to monitor the activity of the router (i.e. making sure it's "live"). I asked the manufacturer of the routers to program them to send a TCP "ping" packet to my server IP address, to a specific port, every 15 minutes, with very basic data for monitoring (router serial number, "I'm alive" string). I have a Windows Server running on a static IP which receives the data. I tested this by sending a packet using netcat, and I can see it's received correctly. I used freeware called Packet Sender to open a specific TCP port and log the incoming traffic. What I need to do now is run code on my server which listens to the specific port, and saves the data (router serial number, time of transmission, etc.) in a DB. This way, customers will later be able to log into their account, and view their router's "activity". There will also be advanced features like notifying the customer whenever the server doesn't receive data from their router over a period of X minutes/hours, etc. I'm asking for advice as to how to set this up in the best way. I read about simple Python code that can listen to a port (like in this answer), and I guess I can use that to save the data to a local DB. But would that be best? What about race conditions (i.e. multiple routers sending data at the same time)? I guess these transmissions wuould need to enter into some basic queue and be dealt with one by one? Is there some good exiting framework I can use that will do all this for me? Any advice as to how to implement this would be great. I know some basic Python backend programming.

Answer: Correct answer with TCP You can basically use https://docs.python.org/3/library/socketserver.html#socketserver-tcpserver-example to accept tcp pings and write it to a database. Demo database using the standard library sqllite3 https://docs.python.org/3/library/sqlite3.html Demo server using standard library Httpserver https://docs.python.org/3.10/library/http.server.html#module-http.server to do some basic fetching import socketserver import time from http.server import HTTPServer, BaseHTTPRequestHandler from threading import Thread import sqlite3 con = sqlite3.connect("test.db", check_same_thread = False) cur = con.cursor() try: cur.execute("CREATE TABLE TCPPING(time, port, data)") except sqlite3.OperationalError: print("Table is already made") def parse_and_add_to_db(line: str, port): cur.execute(f"INSERT INTO TCPPING VALUES('{time.time()}', {port}, '{line}')") def tcp_reciever_thread(): class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler): def handle(self): data = self.request.recv(1024).decode("latin-1") parse_and_add_to_db(data, self.client_address[1]) self.request.sendall(b"ADDED") class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): pass HOST, PORT = "localhost", 6000 ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler).serve_forever() tcp_reciever = Thread(target=tcp_reciever_thread) tcp_reciever.daemon = True tcp_reciever.start() #Server class functionserver(BaseHTTPRequestHandler): def do_GET(self): a, b = self.path[1:].split("/") print(a, b) data = cur.execute(f"SELECT * from TCPPING where {a}=='{b}'").fetchall() #OUTPUT self.send_response(200) self.end_headers() self.wfile.write((("\n".join(map(str,data))).encode())) self.wfile.flush() def log_message(args,*kwargs): return None httpd = HTTPServer(("127.0.0.1", 5000), functionserver) httpd.serve_forever()  client.py import socket ip = "localhost" port = 6000 def client(message): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect((ip, port)) sock.sendall(message.encode()) response = str(sock.recv(1024), 'ascii') print("Received: {}".format(response)) client("abc")  Wrong older answer where I thought it was ICMP ping and used tcp dump to capture  icmp packets do not really have a "port" for listening to. I would suggest using tcpdump to capture this data. If possible you should use standard post requests to get the data. Maxmillion's answer is basically how to scale up an app for enterprise, not how to make it. For accomplishing the basic requirements on local, we only need the standard library and tcpdump.  Overview  We have a database using sqllite3 https://docs.python.org/3/library/sqlite3.html We have a daemon thread that uses subprocess.Popen https://docs.python.org/3/library/subprocess.html to get tcpdump https://www.tcpdump.org/ output, parse it and write it to the database In the main thread we start a Httpserver https://docs.python.org/3.10/library/http.server.html#module-http.server to do some basic fetching  from subprocess import PIPE, Popen from http.server import HTTPServer, BaseHTTPRequestHandler from threading import Thread import sqlite3 con = sqlite3.connect("test.db", check_same_thread = False) cur = con.cursor() try: cur.execute("CREATE TABLE PINGS(time, ip1, ip2, type, id, seq, length)") except sqlite3.OperationalError: print("Table is already made") def parse_and_add_to_db(line: str): line = line.replace(",", "") time, _1, ip1, _2, ip2, _3, _4, type, _5, id, _6, seq, _7, length = line.split() ip2 = ip2[:-1] # print(f"inserting ('{time}', '{ip1}', '{ip2}', '{type}', {id}, {seq}, {length})") cur.execute(f"INSERT INTO PINGS VALUES('{time}', '{ip1}', '{ip2}', '{type}', {id}, {seq}, {length})") def tcpdump_thread(): # proc = Popen("sudo tcpdump -l -w /dev/null -i utun3 icmp --print -f -xx".split(), stdin=PIPE, stdout=PIPE, stderr=PIPE) # if we want the packet hex proc = Popen("sudo tcpdump -l -w /dev/null -i YOURINTERFACE icmp --print -f".split(), stdin=PIPE, stdout=PIPE, stderr=PIPE) # start a process to moitor pings assert proc.stdin is not None and proc.stdout is not None and proc.stderr is not None proc.stdin.write("YOURPASSWORDHERE\n".encode()) # password proc.stdin.flush() print("START") while True: parse_and_add_to_db(proc.stdout.readline().decode("latin-1")) bg_tcpdump = Thread(target=tcpdump_thread) bg_tcpdump.daemon = True bg_tcpdump.start() #Server class functionserver(BaseHTTPRequestHandler): def do_GET(self): a, b = self.path[1:].split("/") print(a, b) data = cur.execute(f"SELECT * from PINGS where {a}=='{b}'").fetchall() #OUTPUT self.send_response(200) self.end_headers() self.wfile.write((("\n".join(map(str,data))).encode())) self.wfile.flush() def log_message(args,*kwargs): return None httpd = HTTPServer(("127.0.0.1", 5000), functionserver) httpd.serve_forever()  You can run this (tcpdump needs sudo and you need to put the correct interface to listen to pings on so you need to configure those) and access localhost:5000/ip1/1.1.1.1 in your browser and run ping 1.1.1.1 in the background and see the database entries pop up. If you want to do some parsing with the packet hex data you can use the line with # if we want the packet hex and you can uncomment the print statement in parse to debug. Hope this helps. Additional  this is a very crude demo code do not directly put strings into sql for queries and possibly have a different process (instead of running the tcpdump and parsing in the server process) Even if you scale up using a proper database and fastapi/flask/django and sqlAlchemy for the server instead of this, the logic should be similar.  For the suggested best practices -  If you do not have a database, choose one on the cloud which will have an api. You don't need to bother about race conditions when using a production quality database. And tcp dump should have no issues keeping up with multiple pings. For alerts you could query the db at regular intervals (polling) for certain conditions from your webapp. For dumping the ping data you just need to dump it from your ping monitoring app. Overall it is not an overly difficult system to design and does not need advanced networking knowledge to create an unoptimized version which works reliably. Using c/c++/rust or other low level languages to get into the kernel/driver/network stack will give much better performance. But this is a python question.