3

I'm trying to create a persistent socket connection between a Lua client and Python server. Effectively a script that'll constantly ping the server with keepalive messages

My current issue is that the socket closes after each connection without a means to reopen it for transmission.

Lua Client:

local HOST, PORT = "localhost", 9999
local socket = require('socket')

-- Create the client and initial connection
client, err = socket.connect(HOST, PORT)
client:setoption('keepalive', true)

-- Attempt to ping the server once a second
start = os.time()
while true do
  now = os.time()
  if os.difftime(now, start) >= 1 then
    data = client:send("Hello World")
    -- Receive data from the server and print out everything
    s, status, partial = client:receive()
    print(data, s, status, partial)
    start = now
  end
end

Python Server:

import socketserver

class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        self.data = self.request.recv(1024).strip()
        print("{} wrote".format(self.client_address[0]))
        print(self.data)
        print(self.client_address)
        # Send back some arbitrary data
        self.request.sendall(b'1')

if __name__ == '__main__':
    HOST, PORT = "localhost", 9999
    # Create a socketserver and serve is forever
    with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
        server.serve_forever()

The expected result is a keepalive ping every second to ensure the client is still connected to the server.

1 Answer 1

2

I ended up finding a solution.

The problem seems to have been with the socketserver library in Python. I switched it to raw sockets and things began working how I wanted them to. From there I created threads to handle the back and forth in the background

Python Server:

import socket, threading

HOST, PORT = "localhost", 9999

# Ensures the connection is still active
def keepalive(conn, addr):
    print("Client connected")
    with conn:
        conn.settimeout(3)
        while True:
            try:
                data = conn.recv(1024)
                if not data: break
                message = data.split(b',')
                if message[0] == b'ping':
                    conn.sendall(b'pong' + b'\n')
            except Exception as e:
                break
        print("Client disconnected")

# Listens for connections to the server and starts a new keepalive thread
def listenForConnections():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        sock.bind((HOST, PORT))
        while True:
            sock.listen()
            conn, addr = sock.accept()
            t = threading.Thread(target=keepalive, args=(conn, addr))
            t.start()

if __name__ == '__main__':
    # Starts up the socket server
    SERVER = threading.Thread(target=listenForConnections)
    SERVER.start()

    # Run whatever code after this

The Lua client didn't change in this scenario

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for asking (and then answering) my question @ThomasR! I'm new to Python, and the various socketserver classes sure do great things out of the box — if that's what you want. But I didn't, my use case is much like yours, and this has definitely gotten me started in the right direction.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.