Socket açık kalan client

Bir server ve birden fazla client olacak. Clientler toplu bağlanabiliyor fakat server kapalıyken program direk çöküyor. Ben serveri bilgisayarıma kuracağım için bazen kapanıyor olabilecek fakat ben clientlerin servere bağlanamasa bile kapanmamasını, bağlantı sağlanabildiğinde bağlanmasını istiyorum. Thread class vb kullanmayı denedim fakat yapamadım yardım edin lütfen

1 Beğeni

socket.socket bağlantı kurulamazsa veya koparsa hata yükseltiyor. Bu hatayı yakalayabilirsiniz.

Hatayı yakalıyorum fakat döngüye sokunca tekrar bağlanamıyor

O zaman kapatip yeni soket ac.

1 Beğeni

Aşağıdaki kodları bir inceleyin isterseniz:

server.py

#!/usr/bin/python3.7
# -*- coding: utf-8 -*-

import socket
import threading


class Server(socket.socket):
    CLIENTS = []
    ADDR = []
    NICKNAMES = []
    DATA = ""

    def __init__(self):
        socket.socket.__init__(self, socket.AF_INET, socket.SOCK_STREAM)
        self.conn = None

    def start(self):
        self.bind(("localhost", 12345))
        self.listen(10)
        print(f"Started on {self.getsockname()}")

    def accept_client(self):
        try:
            conn, addr = self.accept()
            self.conn = conn
            self.CLIENTS.append(conn)
            self.ADDR.append(addr)
            print(f"{addr} connected.")
        except OSError:
            pass

    def receive_data(self):
        if self.conn is not None:
            self.DATA = self.conn.recv(1024).decode("utf-8")
            if "/nick " in self.DATA:
                self.NICKNAMES.append(self.DATA.split()[-1])
                self.DATA = ""

    def send_data(self):
        if self.NICKNAMES:
            for i in self.CLIENTS:
                try:
                    if self.NICKNAMES[self.CLIENTS.index(i)] != \
                            self.DATA.split(":")[0]:
                        try:
                            if len(self.DATA) == 0:
                                pass
                            else:
                                i.send(self.DATA.encode("utf-8"))
                        except BrokenPipeError:
                            print(
                                f"\n{self.ADDR[self.CLIENTS.index(i)]} "
                                f"has been disconnected\n"
                            )
                            self.ADDR.pop(self.CLIENTS.index(i))
                            self.NICKNAMES.pop(self.CLIENTS.index(i))
                            self.CLIENTS.remove(i)
                except IndexError:
                    pass
        self.DATA = ""


def main():
    server = Server()
    threading.Thread(target=server.start).start()
    while True:
        thread_accept = threading.Thread(target=server.accept_client)
        thread_accept.daemon = True
        thread_accept.start()
        thread_accept.join(0.1)
        thread_receive = threading.Thread(target=server.receive_data)
        thread_receive.daemon = True
        thread_receive.start()
        thread_receive.join(0.1)
        thread_send = threading.Thread(target=server.send_data)
        thread_send.daemon = True
        thread_send.start()
        thread_send.join(0.1)


if __name__ == "__main__":
    main()

client.py

#!/usr/bin/python3.7
# -*- coding: utf-8 -*-

import socket
import threading

from datetime import datetime as dt

now = lambda: dt.now().strftime("%Y.%m.%d %H:%M:%S")


class Client(socket.socket):
    online = False
    
    def __init__(self, nickname: str = ""):
        socket.socket.__init__(self, socket.AF_INET, socket.SOCK_STREAM)
        self.nickname = nickname

    def connect_server(self):
        try:
            self.connect(("localhost", 12345))
            self.online = True
            self.sendall(f"/nick {self.nickname}".encode("utf-8"))
        except ConnectionRefusedError:
            print("Server is not active.")

    def receive_data(self):
        try:
            data = self.recv(1024).decode("utf-8")
            if len(data) == 0:
                pass
            else:
                print(data)
        except OSError:
            pass

    def send_data(self):
        respond = input()
        try:
            self.sendall(f"{self.nickname}: {respond}".encode("utf-8"))
        except:
            self.close()
            self.online = False
            del self
               
            
def create_nickname():
    print(f"| {now()} | Welcome to the chat program.\n")
    print("Commands:\n\t/nick <new_nickname>\n".expandtabs(4))
    nickname = input("/nick ")
    while not nickname:
        print("Create a valid nickname.")
        nickname = input("/nick ")
    else:
        print(f"| {now()} | Your nickname has changed to {nickname}.")
        return nickname          


def main():
    while True:
        nickname = create_nickname()
        client = Client(nickname=nickname)
        client.connect_server()
        while client.online:
            threading.Thread(target=client.receive_data).start()
            thread_send = threading.Thread(
                target=client.send_data, daemon=True
            )
            thread_send.start()
            thread_send.join(1)
            
        
if __name__ == "__main__":       
    main()

Bu kodlara sunucunun aktif olup olmadığını anlık olarak kontrol eden bir kod yazmadım. Bu kodlara göre istemci sunucunun aktif olup olmadığını mesaj göndermeye çalışarak anlayabilir. Bu kodlara göre istemci sunucuya otomatik olarak bağlanmaya çalışmaz, ama dilerseniz o şekilde de yapabilirsiniz. Mesela sunucu kapandıktan sonra bir dakika arayla istemci tekrar sunucuya bağlanmaya çalışabilir.

1 Beğeni