Bir de, artık ilk kopan istemci hariç diğer istemcilerin sunucudan koptuğunun bilgisi ekrana da log dosyasına da yazdırılmıyor.
O kısım hakkında bilgim yok. Biraz daha bilgi edindikten sonra bir cevap yazabilirim. Şimdilik bu kadar yorum yapabiliyorum malesef…
Vakit ayırdığınız için teşekkürler. Biraz daha uğraşayım izninizle.
Rica ederim ne demek, kolay gelsin
Sorun çözüldü görünüyor.
#!/usr/bin/env python3.7
# -*- coding: utf-8 -*-
import asyncio
import logging
logging.basicConfig(
filename="server.log",
format="- %(levelname)s - %(asctime)s - %(message)s",
level=logging.DEBUG,
datefmt="%d.%m.%Y %H:%M:%S"
)
class Server:
def __init__(self):
self.clients = []
def run(self):
asyncio.run(self.main())
async def client_connected(self, reader, writer):
client = f"{writer.get_extra_info('peername')}"
print(f"{client} is connected.")
logging.info(f"{client} is connected.")
self.clients.append((writer, reader))
while True:
try:
data = await reader.readline()
except (BrokenPipeError, ConnectionResetError):
data = "".encode()
msg = f"{client}: {data.decode()}"
if msg.encode() == f"{client}: ".encode():
writer.close()
print(f"{client} is disconnected.")
logging.info(f"{client} is disconnected.")
await writer.wait_closed()
self.clients.remove((writer, reader))
break
else:
for i in self.clients:
i[0].write(msg.encode())
logging.debug(msg[:-1])
await i[0].drain()
async def main(self):
server = await asyncio.start_server(
client_connected_cb=self.client_connected,
host="127.0.0.1",
port=12345
)
print(f"Server started on {server.sockets[0].getsockname()}")
logging.info(f"Server started on {server.sockets[0].getsockname()}")
async with server:
await server.wait_closed()
if __name__ == "__main__":
Server().run()
Bu da, log dosyasının içeriği:
- DEBUG - 30.09.2019 22:22:21 - Using selector: EpollSelector
- INFO - 30.09.2019 22:22:21 - Server started on ('127.0.0.1', 12345)
- INFO - 30.09.2019 22:22:27 - ('127.0.0.1', 48864) is connected.
- INFO - 30.09.2019 22:22:31 - ('127.0.0.1', 48866) is connected.
- DEBUG - 30.09.2019 22:22:32 - ('127.0.0.1', 48866): veli: selam
- DEBUG - 30.09.2019 22:22:32 - ('127.0.0.1', 48866): veli: selam
- DEBUG - 30.09.2019 22:22:35 - ('127.0.0.1', 48866): veli: naber?
- DEBUG - 30.09.2019 22:22:35 - ('127.0.0.1', 48866): veli: naber?
- DEBUG - 30.09.2019 22:22:37 - ('127.0.0.1', 48866): veli: iyi misin=
- DEBUG - 30.09.2019 22:22:37 - ('127.0.0.1', 48866): veli: iyi misin=
- DEBUG - 30.09.2019 22:22:41 - ('127.0.0.1', 48864): ali: eyvallah
- DEBUG - 30.09.2019 22:22:41 - ('127.0.0.1', 48864): ali: eyvallah
- DEBUG - 30.09.2019 22:22:42 - ('127.0.0.1', 48864): ali: kardeş
- DEBUG - 30.09.2019 22:22:42 - ('127.0.0.1', 48864): ali: kardeş
- INFO - 30.09.2019 22:22:43 - ('127.0.0.1', 48864) is disconnected.
- INFO - 30.09.2019 22:22:47 - ('127.0.0.1', 48868) is connected.
- DEBUG - 30.09.2019 22:22:49 - ('127.0.0.1', 48868): eheh: selam
- DEBUG - 30.09.2019 22:22:49 - ('127.0.0.1', 48868): eheh: selam
- DEBUG - 30.09.2019 22:22:50 - ('127.0.0.1', 48868): eheh: naber?
- DEBUG - 30.09.2019 22:22:50 - ('127.0.0.1', 48868): eheh: naber?
- INFO - 30.09.2019 22:22:50 - ('127.0.0.1', 48868) is disconnected.
Aşağıdaki ifadeye göre kodları yeniden düzenledim:
try:
data = await reader.readline()
except (BrokenPipeError, ConnectionResetError):
data = "".encode()
Bu iki duruma göre, ya istemciden okunan veri diğer istemcilere gönderilmeye çalışılacak ya da boş bir data
verisi kullanıcıya gönderilmeye çalışılacak.
O halde şöyle bir sorgu kullanabiliriz diye düşündüm:
msg = f"{client}: {data.decode()}"
if msg.encode() == f"{client}: ".encode():
Bu koşul altında hata veren writer
'ı self.clients
içinde aramak yerine, doğrudan writer
'ı kapatmaya çalıştım. Daha sonra writer
kapatılana kadar beklemeye alınır. Kapatıldıktan sonra da self.clients
listesinden kopmuş istemcinin writer
ve reader
özellikleri düşürülür. Ve while
döngüsü sonlandırılır.
else
koşulunda ise self.clients
listesindeki her bir istemciye mesaj gönderilir.
Evet boş mesaj sorunu çözülmüş görünüyor. Ancak bu sefer de şu hatayı veriyor
- ERROR - 30.09.2019 22:50:28 - Task exception was never retrieved
Client bağlantısını yapan cmd ekranını kapatınca böyle oluyor. Diğer türlü sonlandıramıyorum.
O hatayı daha önce birçok kez aldım. Bu arada logun tamamına bakabilir miyim izninizle? Son çalıştırdığımda şöyle bir log aldım:
- DEBUG - 30.09.2019 22:54:55 - Using selector: EpollSelector
- INFO - 30.09.2019 22:54:55 - Server started on ('127.0.0.1', 12345)
- INFO - 30.09.2019 22:54:58 - ('127.0.0.1', 48996) is connected.
- INFO - 30.09.2019 22:55:03 - ('127.0.0.1', 48998) is connected.
- DEBUG - 30.09.2019 22:55:05 - ('127.0.0.1', 48998): veli: selam
- DEBUG - 30.09.2019 22:55:05 - ('127.0.0.1', 48998): veli: selam
- DEBUG - 30.09.2019 22:55:06 - ('127.0.0.1', 48998): veli: naber*
- DEBUG - 30.09.2019 22:55:06 - ('127.0.0.1', 48998): veli: naber*
- DEBUG - 30.09.2019 22:55:07 - ('127.0.0.1', 48998): veli: ahahaha
- DEBUG - 30.09.2019 22:55:07 - ('127.0.0.1', 48998): veli: ahahaha
- INFO - 30.09.2019 22:55:12 - ('127.0.0.1', 49000) is connected.
- DEBUG - 30.09.2019 22:55:13 - ('127.0.0.1', 49000): ahaha: ahaha
- DEBUG - 30.09.2019 22:55:13 - ('127.0.0.1', 49000): ahaha: ahaha
- DEBUG - 30.09.2019 22:55:13 - ('127.0.0.1', 49000): ahaha: ahaha
- DEBUG - 30.09.2019 22:55:13 - ('127.0.0.1', 49000): ahaha: ahaha
- DEBUG - 30.09.2019 22:55:13 - ('127.0.0.1', 49000): ahaha: ahaha
- DEBUG - 30.09.2019 22:55:13 - ('127.0.0.1', 49000): ahaha: ahaha
- DEBUG - 30.09.2019 22:55:14 - ('127.0.0.1', 49000): ahaha: ahaha
- DEBUG - 30.09.2019 22:55:14 - ('127.0.0.1', 49000): ahaha: ahaha
- DEBUG - 30.09.2019 22:55:14 - ('127.0.0.1', 49000): ahaha: ahaha
- DEBUG - 30.09.2019 22:55:17 - ('127.0.0.1', 49000): ahaha: naber?
- DEBUG - 30.09.2019 22:55:17 - ('127.0.0.1', 49000): ahaha: naber?
- DEBUG - 30.09.2019 22:55:17 - ('127.0.0.1', 49000): ahaha: naber?
- INFO - 30.09.2019 22:55:19 - ('127.0.0.1', 49000) is disconnected.
- INFO - 30.09.2019 22:55:23 - ('127.0.0.1', 49002) is connected.
- DEBUG - 30.09.2019 22:55:25 - ('127.0.0.1', 49002): ehehe: hahahaha
- DEBUG - 30.09.2019 22:55:25 - ('127.0.0.1', 49002): ehehe: hahahaha
- DEBUG - 30.09.2019 22:55:25 - ('127.0.0.1', 49002): ehehe: hahahaha
- INFO - 30.09.2019 22:55:25 - ('127.0.0.1', 49002) is disconnected.
- DEBUG - 30.09.2019 22:55:28 - ('127.0.0.1', 48998): veli: wfkwkf
- DEBUG - 30.09.2019 22:55:28 - ('127.0.0.1', 48998): veli: wfkwkf
- INFO - 30.09.2019 22:55:29 - ('127.0.0.1', 48998) is disconnected.
- DEBUG - 30.09.2019 22:55:33 - ('127.0.0.1', 48996): ali: ajajaa
- INFO - 30.09.2019 22:55:34 - ('127.0.0.1', 48996) is disconnected.
Tabi ki
DEBUG - 30.09.2019 22:54:58 - Using selector: SelectSelector
- INFO - 30.09.2019 22:54:58 - Server started on ('127.0.0.1', 12345)
- INFO - 30.09.2019 22:55:16 - ('127.0.0.1', 49857) is connected.
- INFO - 30.09.2019 22:55:24 - ('127.0.0.1', 49860) is connected.
- DEBUG - 30.09.2019 22:55:32 - ('127.0.0.1', 49857): user1: merhaba
- DEBUG - 30.09.2019 22:55:32 - ('127.0.0.1', 49857): user1: merhaba
- DEBUG - 30.09.2019 22:55:36 - ('127.0.0.1', 49860): user2: merhaba kardeş
- DEBUG - 30.09.2019 22:55:36 - ('127.0.0.1', 49860): user2: merhaba kardeş
- DEBUG - 30.09.2019 22:55:47 - ('127.0.0.1', 49857): user1: by
- DEBUG - 30.09.2019 22:55:47 - ('127.0.0.1', 49857): user1: by
- INFO - 30.09.2019 22:55:55 - ('127.0.0.1', 49857) is disconnected.
- ERROR - 30.09.2019 22:55:55 - Task exception was never retrieved
future: <Task finished coro=<Server.client_connected() done, defined at a_server.py:23> exception=ConnectionResetError(10054, 'Varolan bir bağlantı uzaktaki bir ana bilgisayar tarafından zorla kapatıldı', None, 10054, None)>
Traceback (most recent call last):
File "a_server.py", line 38, in client_connected
await writer.wait_closed()
File "C:\Python37\lib\asyncio\streams.py", line 323, in wait_closed
await self._protocol._closed
File "a_server.py", line 30, in client_connected
data = await reader.readline()
File "C:\Python37\lib\asyncio\streams.py", line 496, in readline
line = await self.readuntil(sep)
File "C:\Python37\lib\asyncio\streams.py", line 588, in readuntil
await self._wait_for_data('readuntil')
File "C:\Python37\lib\asyncio\streams.py", line 473, in _wait_for_data
await self._waiter
File "C:\Python37\lib\asyncio\selector_events.py", line 804, in _read_ready__data_received
data = self._sock.recv(self.max_size)
ConnectionResetError: [WinError 10054] Varolan bir bağlantı uzaktaki bir ana bilgisayar tarafından zorla kapatıldı
- DEBUG - 30.09.2019 22:56:00 - ('127.0.0.1', 49860): user2: by
- ERROR - 30.09.2019 22:56:00 - Task exception was never retrieved
future: <Task finished coro=<Server.client_connected() done, defined at a_server.py:23> exception=ConnectionResetError(10054, 'Varolan bir bağlantı uzaktaki bir ana bilgisayar tarafından zorla kapatıldı', None, 10054, None)>
Traceback (most recent call last):
File "a_server.py", line 45, in client_connected
await i[0].drain()
File "C:\Python37\lib\asyncio\streams.py", line 339, in drain
raise exc
File "a_server.py", line 38, in client_connected
await writer.wait_closed()
File "C:\Python37\lib\asyncio\streams.py", line 323, in wait_closed
await self._protocol._closed
File "a_server.py", line 30, in client_connected
data = await reader.readline()
File "C:\Python37\lib\asyncio\streams.py", line 496, in readline
line = await self.readuntil(sep)
File "C:\Python37\lib\asyncio\streams.py", line 588, in readuntil
await self._wait_for_data('readuntil')
File "C:\Python37\lib\asyncio\streams.py", line 473, in _wait_for_data
await self._waiter
File "C:\Python37\lib\asyncio\selector_events.py", line 804, in _read_ready__data_received
data = self._sock.recv(self.max_size)
ConnectionResetError: [WinError 10054] Varolan bir bağlantı uzaktaki bir ana bilgisayar tarafından zorla kapatıldı
Kullanıcı 1 bağlandı, kullanıcı 2 bağlandı. Daha sonra kullanıcı1 mesaj gönderdikten sonra cmd ekranını kapattım. Ve kullanıcı2 penceresini de kapattım.
Server üzerinde kullanıcı 1 için sonlandı yazıyor ama, kullanıcı 2 için yazmıyor
Şaşkın şaşkın bakıyorum paylaştığınız ekran çıktısına. Acaba bu hatayı neye bağlı olarak veriyor?
İnanın ben de bilmiyorum. Ama çözmek için uğraşıyorum.
Acaba Windows’tan mı kaynaklanıyor anlamadım ki. Mesela aşağıdaki çıktı son aldığım çıktı ve hiç hata gözükmüyor.
- DEBUG - 30.09.2019 23:06:36 - Using selector: EpollSelector
- INFO - 30.09.2019 23:06:36 - Server started on ('127.0.0.1', 12345)
- INFO - 30.09.2019 23:06:39 - ('127.0.0.1', 49016) is connected.
- INFO - 30.09.2019 23:06:40 - ('127.0.0.1', 49016) is disconnected.
- INFO - 30.09.2019 23:06:45 - ('127.0.0.1', 49018) is connected.
- INFO - 30.09.2019 23:06:46 - ('127.0.0.1', 49018) is disconnected.
- INFO - 30.09.2019 23:06:49 - ('127.0.0.1', 49020) is connected.
- INFO - 30.09.2019 23:06:50 - ('127.0.0.1', 49020) is disconnected.
- INFO - 30.09.2019 23:06:52 - ('127.0.0.1', 49022) is connected.
- INFO - 30.09.2019 23:06:53 - ('127.0.0.1', 49022) is disconnected.
- INFO - 30.09.2019 23:07:11 - ('127.0.0.1', 49024) is connected.
- INFO - 30.09.2019 23:07:11 - ('127.0.0.1', 49024) is disconnected.
- INFO - 30.09.2019 23:07:14 - ('127.0.0.1', 49026) is connected.
- INFO - 30.09.2019 23:07:15 - ('127.0.0.1', 49026) is disconnected.
- INFO - 30.09.2019 23:07:17 - ('127.0.0.1', 49028) is connected.
- INFO - 30.09.2019 23:07:22 - ('127.0.0.1', 49030) is connected.
- INFO - 30.09.2019 23:07:23 - ('127.0.0.1', 49030) is disconnected.
- INFO - 30.09.2019 23:07:26 - ('127.0.0.1', 49032) is connected.
- INFO - 30.09.2019 23:07:26 - ('127.0.0.1', 49032) is disconnected.
- INFO - 30.09.2019 23:07:28 - ('127.0.0.1', 49034) is connected.
- INFO - 30.09.2019 23:07:29 - ('127.0.0.1', 49034) is disconnected.
- INFO - 30.09.2019 23:07:32 - ('127.0.0.1', 49036) is connected.
- INFO - 30.09.2019 23:07:32 - ('127.0.0.1', 49036) is disconnected.
- INFO - 30.09.2019 23:07:35 - ('127.0.0.1', 49038) is connected.
- DEBUG - 30.09.2019 23:07:36 - ('127.0.0.1', 49038): b: aaa
- DEBUG - 30.09.2019 23:07:36 - ('127.0.0.1', 49038): b: aaa
- DEBUG - 30.09.2019 23:07:37 - ('127.0.0.1', 49038): b: ehehehe
- DEBUG - 30.09.2019 23:07:37 - ('127.0.0.1', 49038): b: ehehehe
- INFO - 30.09.2019 23:07:38 - ('127.0.0.1', 49038) is disconnected.
- INFO - 30.09.2019 23:07:44 - ('127.0.0.1', 49040) is connected.
- DEBUG - 30.09.2019 23:07:45 - ('127.0.0.1', 49040): akaka: wkfwkf
- DEBUG - 30.09.2019 23:07:45 - ('127.0.0.1', 49040): akaka: wkfwkf
- DEBUG - 30.09.2019 23:07:45 - ('127.0.0.1', 49040): akaka: wfwf
- DEBUG - 30.09.2019 23:07:45 - ('127.0.0.1', 49040): akaka: wfwf
- INFO - 30.09.2019 23:07:46 - ('127.0.0.1', 49040) is disconnected.
- INFO - 30.09.2019 23:07:47 - ('127.0.0.1', 49028) is disconnected.
Siz bağlantıyı nasıl sonlandırıyorsunuz acaba merak ettim. Ben CTRL-C ile sonlandıramıyorum. Onun yerine pencereyi kapatmak durumunda kalıyorum.
Evet, ctrl-c ile sonlandırıyorum.
Siz öyle deyince, X işaretinden sonlandırayım dedim ancak değişen bir şey olmadı.
Anladım. Windows cmd üzerinden CTRL-C ile kapatamadım henüz… Ancak kapanmadığı halde, mesaj gönderilemiyor. Sadece imlec yanıp sönüyor, mesaj girişi yapılamıyor.
Bunlar benim bilgisayarımdaki denemelerim. Başkaları da denerse, belki daha farklı sonuçlar elde edebiliriz
Client penceresinin tam kapanmaması thread’den kaynaklanıyor olabilir belki.
Kodlarda şöyle bir değişiklik yapılsa nasıl olur?
Mesela son satırda Client
sınıfından bir örnek oluşturup bunun run
metodunu çağırmak yerine, bir thread oluşturulur ve run
metodu thread’e argüman olarak aktarılır. Bilmiyorum daha denemedim. Şunun gibi:
if __name__ == "__main__":
t_main = threading.Thread(target=lambda: Client().run())
t_main.run()
Bilmiyorum ama, bana nedense pek bir şey değişmeyecek gibi geliyor.
Windows’ta programı ctrl-c ile kapatabilmek içindi bu kodlar bu arada. Daha önce threadler yüzünden böyle bir durumla karşılaşmıştım.
Dediğiniz şekilde değişiklik yaptım. Ancak aynı durum devam ediyor. CTRL-C ile kapatılmıyor.