Python ile Socket Programlama 2
Merhabalar, Bir önceki bloğumuzda yazdığımız örneği bu sefer AsyncIO ile yazacağız fakat öncesinde biraz bilgi verelim mesela TCP/UDP nedir, aralarında ki fark nelerdir ?
TCP/UDP nedir, aralarında ki fark nelerdir ?
- TCP => Transmission Control Protocol (İletim Denetimi Protokolü)
- UDP => User Datagram Protocol (Kullanıcı Datagram Protokolü)
TCP ve UDP socket programlamada kullanılan protokollerdir. Verinin nasıl iletileceğini belirtirler.
TCP veriyi iletir veriyi ilettiğine dair bilgi mesajı döner. Eğer veri paketi kaybolduysa paket bir daha gonderilir.
UDP ise gönderilecek verileri sürekli iletir fakat herhangi bir iletildi mesajı almaz. Bu protokolde paket kaybolsa dahi bir şey yapılmaz. Çoğunlukla video ve ses iletiminde kullanılır.
AsyncIO ile Basit Socket Örneği
AsyncIO öğrenmek için tıklayınız.
# server.py import socket import asyncio HEADER = 64 IP = socket.gethostbyname(socket.gethostname()) PORT = 9999 ADDR = (IP, PORT) FORMAT = 'utf-8' DISCONNECT_MESSAGE = "DISCONNECT_SERVER_CODE" server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(ADDR) server.setblocking(False) async def handle_client(conn, addr): print(f"[New Connection] {addr} connected...") loop = asyncio.get_event_loop() connected = True while connected: max_lenth = await loop.sock_recv(conn, HEADER) max_lenth = max_lenth.decode(FORMAT) if max_lenth: max_lenth = int(max_lenth) msg = await loop.sock_recv(conn, max_lenth) msg = msg.decode(FORMAT) if msg == DISCONNECT_MESSAGE: print("[Disconnect] Disconnecting from server") connected = False print(f"[{addr}] -> {msg}") # Do whatever you want with message print(f"{len(asyncio.all_tasks())}") else: print( f"Connection Closed by Client Connection will remove in server {addr}") connected = False conn.close() async def start(): server.listen() print(f"[Listening] Server is Listening now on {IP}") loop = asyncio.get_event_loop() while True: conn, addr = await loop.sock_accept(server) loop.create_task(handle_client(conn, addr)) if __name__ == "__main__": print("[Starting] Socket Server is starting... Stand By") asyncio.run(start())
Server kodunu incelediğimizde nerdeyse bir önceki blog yazısındaki örnek ile ayni olduğunu göreceğiz tek değişen şey Thread yerine AsyncIO kullanılmış olması. Bu kodda low level AsyncIO kullanılmıştır.
loop = asyncio.get_event_loop() while True: conn, addr = await loop.sock_accept(server) loop.create_task(handle_client(conn, addr))
Yukarıdaki kodda loop’a atadığımız şey sistemin o anki çalıştırdığı taskları getirir. Eğer çalışan task yoksa yeni bir task listesi olusturup onu donduruyor. create_task ile fonksiyonumuz task listesine atıyoruz. Bu işlem while döngüsü içerisinde yapıldığından her gelen istek için bir task atanıyor ve Async olarak çalıştırılıyor.
Geri kalan kod parçacığı ayni olsa da fonksiyonların Async tanımlandığını ve await ile kodun bekletildiğini görüyoruz. Eğer bu kavramları bilmiyorsanız AsyncIO blog yazımı okumalısınız.
# client.py import socket HEADER = 64 PORT = 9999 FORMAT = 'utf-8' DISCONNECT_MESSAGE = "DISCONNECT_SERVER_CODE" IP = socket.gethostbyname(socket.gethostname()) ADDR = (IP, PORT) client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(ADDR) def send(msg): message = msg.encode(FORMAT) msg_lenth = str(len(message)).encode(FORMAT) header = msg_lenth + b' ' * (HEADER - len(msg_lenth)) client.send(header) client.send(message) while True: a = input() send(a) # send("Hello World 1") # send("Hello MESSAGE 2") # send("Hello MESSAGE 3") # send("Hello MESSAGE 4")
- Server.py ve Client.py Çıktısı
client.py dosyasını incelediğimizde öncekinden tek farkının kullanıcıdan input alması olduğunu görüyoruz.
Bir sonraki Socket Programlama blog yazısında Python ile one to one (1’e 1) Chat uygulaması yazacağız.