Socket de sunucuya birden fazla client nasıl bağlarım?

Socket de sunucuya birden fazla client bağlayıp, clientlerden aynı anda yada farklı zamanlarda gelen veriyi kontrol edip hepsine farklı cevap nasıl verebilirim acaba?. Bunu araştırdım kullanış olarak threading buldum. Örneklerine de baktım denedim ama bunu socket ile kullanmayı düzgün yapamadım. aşağıda yazdığım kod üstünde yapabilir misiniz?

#socket.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket
import threading
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("localhost",1122))
s.listen(10)
baglantı, adres = s.accept()
while True:
    try:
        veri = baglantı.recv(1024)
        if str(veri.decode()) == "1234":
            baglantı.send("t".encode())
        else:
            baglantı.send("f".encode())
    except ConnectionResetError:
        baglantı, adres = serverSocket.accept()
#client.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket
import threading

c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c.connect(("localhost",1122))


while True:
    veri = input("Parola: ")
    c.send(veri.encode())
    dataFromServer = c.recv(1024)
    if str(dataFromServer.decode()) == "t":
        print("Dogru parola")

    else:
        print("Yanlı Parola")

Şöyle bir server işinizi görür:

import socket
import threading

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("localhost",1122))
s.listen(10)

def recv_and_send_loop(baglantı):
    while True:
        veri = baglantı.recv(1024)
        if str(veri.decode()) == "1234":
            baglantı.send("t".encode())
        else:
            baglantı.send("f".encode())

while True:
    baglantı, adres = s.accept()
    threading.Thread(target = recv_and_send_loop, args = (baglantı,)).start()

Client’te threading’e gerek yok.

Ama 1-2 denemeden sonra bağlanan iki client den birine cevap gelmiyor.

Sadece ilk bağlanan cliente cevap gidiyor.

Hmm bi bakiyim.

Server açtıktan sonra iki kere client dosyalarını açıyorum, ikiside çalışıyor sonra sıra sıra her bir clientden servara cevap gönderiyorum ama clientlerde (galiba ilk açtığım) birinde cevap gelmiyor, kalıyor öyle. Ama diger client çalışıyor.

Benim dikkatsizliğimden:

def recv_and_send_loop(bağlantı):

Fonksiyonu kendim yazdım ama gövdesini sizden kopyaladım, siz bağlantı yerine baglantı kullanmışsınız. Ya Türkçe yazın ya İngilizce, baglantı da ne? :smile:

Şunu deneyebilirsiniz:

import socket
import threading

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("localhost",8000))
s.listen(10)

def recv_and_send_loop(baglantı):
    while True:
        veri = baglantı.recv(1024)
        if veri.decode() == "1234":
            baglantı.send(b"t")
        else:
            baglantı.send(b"f")

while True:
    baglantı, adres = s.accept()
    threading.Thread(target = recv_and_send_loop, args = (baglantı,)).start()

ğ harfi sıkıntı çıkarır diye öyle yazdım. çok deneme yaptım kafam artık oralara gitti.:sweat_smile: sonuç olarak çalışdı, bu kadar kısa olucağını tahmin etmedim, baktığım örneklerin hepsi farklıydı.

Python3’de unicode harfler kullanılabiliyor.

Aslında internetten socket için threading örneği değil de threading için threading örneği araştıysadınız öğrendiklerinizi kendiniz de uygulayabilirdiniz. Socket için threading örneklerinin çoğu zaten threading modülünü bildiğinizi varsayar.

Demek o yüzden yapamadım. :slight_smile: bir şey daha, peki bu s.listen(10) da 10 kişiye kadar kabul edebilyor bunun sınırı yok mu?

Vereceğiniz sayının sınırını soruyorsanız ya fiziksel hafıza ile ya da işletim sistemi sabit bir büyüklükte int kullanıyorsa onunla alakalıdır. Tabii ki sınırı var.

Hayır. :smiley: yani ben oraya 99999999… yazsam o kadar kişi kaldırabilecek mi yani?

Mesela:

Traceback (most recent call last):
  File "C:\Users\Dinçel\Desktop\server.py", line 6, in <module>
    s.listen(918293081039889132789)
OverflowError: Python int too large to convert to C long

Yani bu pc nin gücü ile mi ilgili? mesala server pc leri daha güçlü galiba.

Verilen hataya bakarsak long veri tipinin kaç byte olduğu ile alakalı. Ama bunu kafaya takmanıza gerek yok, sizin için yeterine büyük sayıları kabul edecektir.

Ne yazık ki dediğinizde düzgün bir şey anlamadım, biraz daha ayrıntı ekler misiniz?

CPython C dilinde yazıldığı ve socket modülü C dilindekinin wrapperi olduğu için Python integer’ini C integer’ine dönüştürmeye çalışıyor. C dilinde değişkenlerin kapladıkları alanlar sabit.

Zaten bu sayı sırada kabul edilmeyen en fazla kaç tane bağlantı isteği bulunabileceğini belirliyor, sunucunun kabul edebileceği bağlantı sınırını değil.

Tamam şimdi anladım. Teşekkürler… :slight_smile:

Kusura bakmayın ama ufak bir sorum daha oldu.
client serverdan çıkınca server çöküyor aynı şekilde server kapatılınca client, ben de bunu ekledim. Bunun daha düzgün bir çözümü var mı? client kısmı içinde ekran da bir hata mesajı olabilir belki.

import socket
import threading

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("localhost",1122))
s.listen(10)

def recv_and_send_loop(baglantı):
    while True:
        try:
            veri = baglantı.recv(1024)
            if veri.decode() == "1234":
                baglantı.send(b"t")
            else:
                baglantı.send(b"f")
        except ConnectionResetError:
            pass

while True:
    try:
        baglantı, adres = s.accept()
        threading.Thread(target = recv_and_send_loop, args = (baglantı,)).start()
    except ConnectionResetError:
        pass

Bir thread’daki hata diğer thread’ları etkilemediği için çökmüyor, sadece ekrana hata mesajını yazıyor. Mesajı engellemek isterseniz recv_and_send_loop içindeki try except yeterli.

1 Beğeni