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