Expected 5 arguments given 4 in socker server constructor overriding

231 views Asked by At

I'm trying to override the constructor of the TCPHandler class so that I can pass variables to the handler function, I have come across other posts on stack but they weren't clear to me. I have to pass a byte array to the sendall function in the handle() method, and on looking up for different approaches to do the above, overriding the constructor was the most preferred option.

The is my code:

import SocketServer
class MyTCPHandler(SocketServer.BaseRequestHandler):
    """
    :file:   TCP Handler
    :author: Prat, Warsaw, PL
    """
    def handle(self):

            self.data = self.request.recv(1024).strip()
            print "{} Sent: {}".format(self.client_address[0], self.data[0:3])

            self.request.sendall(bytearray(self.payload_))
            server.server_close()

class superTCPHandler(SocketServer.TCPServer):
        def __init__(self,request, client_address, server, payload_):
            self.payload_ = (payload_)
            SocketServer.TCPServer.__init__(self,request, client_address, BaseRequestHandler, payload_)


        def handle(self):
            self.data = self.request.recv(1024).strip()
            print "{} Sent: {}".format(self.client_address[0], self.data[0:3])


            self.request.sendall(self.payload_)
            print self.payload_ 
            server.server_close()

if __name__ == "__main__": 
            print (help(superTCPHandler ))

            HOST, PORT = "192.168.4.4", 12345
            #server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
            custom_server = SocketServer.TCPServer((HOST, PORT), superTCPHandler, bytearray([114, 100, 100 ,100, 2]))
            print "Listening on {}:{}".format(HOST, PORT)
            custom_server.handle_request()

When I print out the help(superTCPHandler)), the handle() function does not show its inheritance, the code compiles but does nothing, or the client receives nothing. I'm assuming that the handle() function isn't being called from my custom class. I do have a strong feeling that the mistake is somewhere in the __init__ part, i tried multiple times with different approaches, but didn't work out. What is the correct method to do so?

I'm not sure if I have to create an object of the basic class(MyTCPHandler) hence I have commented the server object before initializing custom_server object. I'm kinda new to socket programming, please forgive me for my blind mistakes.

This is the error I get:

custom_server = superTCPHandler((HOST, PORT), superTCPHandler, bytearray([114, 100, 100 ,100, 2]))

TypeError: init() takes exactly 5 arguments (4 given)
[Finished in 0.1s with exit code 1]

1

There are 1 answers

0
Mark Tolonen On

There were a number of issues:

  • superTCPHandler is not a handler because it is derived from TCPServer.
  • The signature of __init_ is wrong in superTCPHandler.
  • custom_server doesn't instantiate a derived TCPServer class.

The following code derives a custom server that takes an additional payload parameter. That parameter is added as a member variable of the server instance. The handler retrieves the server instance's payload.

#!python2
import SocketServer
class MyTCPHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        self.data = self.request.recv(1024).strip()
        print "{} Sent: {}".format(self.client_address[0], self.data[0:3])
        self.request.sendall(bytearray(self.server.payload_))

class superTCPServer(SocketServer.TCPServer):
    def __init__(self, server_address, RequestHandlerClass, payload_, bind_and_activate=True):
        self.payload_ = payload_
        SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate)

if __name__ == "__main__": 
    HOST,PORT = '',12345
    custom_server = superTCPServer((HOST, PORT), MyTCPHandler, bytearray([114, 100, 100 ,100, 2]))
    print "Listening on {}:{}".format(HOST, PORT)
    custom_server.handle_request()