Python Forum
Poll: Bad or not bad
You do not have permission to vote in this poll.
Bad
50.00%
1 50.00%
Not so bad
50.00%
1 50.00%
Total 2 vote(s) 100%
* You voted for this item. [Show Results]

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
My own Lan system
#1
Hey, I recently create a game, who need a comunication between 2 player and I came out with this, I just wan't to know if this code is not too terrible.
import socket

class LanBrick:
    __slots__ = 'port', 'host', 'sock', 'connected', 'in_co', 'serv_sock', '__next_msg_send', 'last_recv', 'is_host', 'disconected'
    length_end: int = b'-'[0]

    def __init__(self, host: str, port: int):
        self.port: int = port
        self.host: str = host
        self.sock: socket.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connected: bool = False
        self.in_co: bool = False
        self.is_host: bool = False
        self.serv_sock: socket.socket = None
        self.disconected: bool = False # use to indicate that the connection just break, should be active only for 1 frame
        self.__next_msg_send: bytes = b'' # store all the message that will be send when next is call
        self.last_recv: bytes = b'' # store all the data receive since the __next__ method is call

    def connect(self) -> None:
        if not self.in_co:
            self.sock = self.new_socket()
            try:
                # try to be a client
                socket.setdefaulttimeout(2.)
                self.sock.connect((self.host, self.port))
            except ConnectionRefusedError:
                # the program failed to connect, that mean that there is no server waiting so the program will create a server
                socket.setdefaulttimeout(0.0)
                self.sock.close()
                self.in_co = True
                self.is_host = True
                self.serv_sock = self.new_socket()
                self.serv_sock.setblocking(0)
                self.serv_sock.bind(('', self.port))
                self.serv_sock.listen(0)
            except socket.timeout:
                socket.setdefaulttimeout(0.0)
                self.sock.close()
                self.in_co = True
                self.is_host = True
                self.serv_sock = self.new_socket()
                self.serv_sock.setblocking(0)
                self.serv_sock.bind(('', self.port))
                self.serv_sock.listen(1)
            else:
                socket.setdefaulttimeout(0.0)
                self.connected = True
                return

        try:
            # see if any client try to connect, this is try for every call of __next__ as long as no client is found
            self.sock, _ = self.serv_sock.accept()
        except BlockingIOError:
            pass # just mean that tere is not client
        else:
            self.sock.setblocking(1)
            self.connected = True
            self.in_co = False

    def disconect(self) -> None:
        if self.connected:
            self.sock.send(b'-') # a msg with no length before the - mean an end connection msg
            self.connected = False
            if self.is_host:
                self.serv_sock.close()
                self.serv_sock = self.new_socket()
        self.in_co = False

    def recv(self) -> bytes:
        return self.last_recv

    def send(self, msg: bytes) -> None:
        if self.connected:
            self.__next_msg_send += msg

    @staticmethod
    def new_socket() -> socket.socket:
        return socket.socket(socket.AF_INET, socket.SOCK_STREAM)


    def __next__(self):
        # a method meant to be call every frame and meant to contain all the communication stuff
        if self.disconnected:
            self.disconnected = False
        if self.connected:
            try:
                self.sock.send(str(len(self.__next_msg_send)).encode('utf-8') + b'-' + self.__next_msg_send)
                self.__next_msg_send = b''

                recv_length: bytes = self.sock.recv(1)
                while recv_length[-1] != self.length_end:
                    recv_length += self.sock.recv(1)
                if recv_length == b'-':
                    self.connected = False
                    if self.is_host:
                        self.is_host = False
                        self.serv_sock.close()
                        self.serv_sock = None
                    self.disconected = True
                    self.sock = self.new_socket()
                else:
                    msg_length: int = int(recv_length[:-1])
                    self.last_recv = self.sock.recv(msg_length)
            except ConnectionResetError:
                self.connected = False
                self.is_host = False
                self.disconected = True
                self.sock = self.new_socket()

        elif self.in_co:
            self.connect()
If you wan't to use it you create a class that inherit from LanBrick and put all the communication stuff that you game need in that class (LanBrick.__next__(self) if meant to be call using next(instance_of_LanBrick) and every frame)

I want to know if this program is bad or not, I think it's bad because it need communication during all the connection, syncing the FPS between the 2 player(if you use this for a game)
Reply


Messages In This Thread
My own Lan system - by Phidias618 - May-23-2023, 03:58 PM
RE: My own Lan system - by DigiGod - May-26-2023, 12:18 AM
RE: My own Lan system - by Phidias618 - May-26-2023, 07:24 PM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020