import socket
import threading


class TCP_Client_1:

    def __init__(self, host, port):
        self.host = host
        self.port = port

    def request(self):
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client.connect((self.host, self.port))
        client.send(b'GET / HTTP/1.1\r\nHost: google.com\r\n\r\n')
        response = client.recv(4096)
        print(response.decode())
        client.close()    


class UDP_Client_1:

    def __init__(self, host, port):
        self.host = host
        self.port = port

    def request(self):
        client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        client.sendto(b'DFLJASLDF', (self.host, self.port))
        data, addr = client.recvfrom(4096)
        print(data.decode())
        client.close()


class TCP_Server:

    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

    
    def main(self):
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.bind((self.ip, self.port))
        server.listen(5)
        print(f'[*] Listening on {self.ip}:{self.port}')

        while True:
            client, address = server.accept()
            print(f'[*] Accepted connection from {address[0]}:{address[1]}')
            client_handler = threading.Thread(target=self.handle_client, args=(client,))
            client_handler.start()


    def handle_client(self, client_socket):
        with client_socket as sock:
            request = sock.recv(1024)
            print(f'[*] Received: {request.decode("utf-8")}')
            sock.send(b'ACK')
                  




def main():
    # client = TCP_Client_1('google.com', 80)
    # client.request()

    # client = UDP_Client_1('127.0.0.1', 9997)
    # client.request()

    server = TCP_Server('127.0.0.1', 80)
    server.main()


if __name__ == '__main__':
    main()