import socket
import time
import threading
clients= {}
host='xxxx'
port=xxxx
addr=(host,port)
server=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print ("socket oluşturuldu...")
server.bind(addr)
print("Socket {} nolu porta bağlandı".format(port))
server.listen(5)
print("Socket dinleniyor bağlantı bekleniyor...")
c,addr= server.accept()
print("1. Şahıs Bağlandı...",addr)
print("2. Şahıs Dinleniyor...")
server.listen(5)
c2,addr= server.accept()
print("2. Şahıs Bağlandı... {}".format(addr))
mesaj=c.recv(50)
print(mesaj)
mesaj2=c2.recv(50)
print(mesaj2)
#c den gelen mesaj c2 ye gidiyor
gidenmesaj=c2.send(mesaj)
while True:
modülğ=threading.Thread(target=addr, args=())
modülğ.start
client:
import socket
import threading
import time
host='xxxx'
port=xxxx
addr=(host,port)
server=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("192.168.56.1:4444 numaralı port üzerinden sockete bağlanılıyor... # BY egecanlıTR")
server.connect(addr)
print("servere bağlanıldı")
def c_den_gelen_mesaj ():
while True:
msg_al=server.recv(50)
print(msg_al)
modül=threading.Thread(target=c_den_gelen_mesaj,args=())
modül.start()
while True:
msg_gönder=input("[CLİENT] MESAJ: ")
server.send(msg_gönder.encode())
time.sleep(0.5)
c_den_gelen_mesaj()
Merhaba, ben bir chat programı yaptım. Serverın görevi ‘client-client’ bağlantısı kurmak, client 1 e c dedim 2. cliente de c2 dedim ‘c den gelen mesaj c2 ye gitsin’ diye bir kod yazdım server e evet gidiyor, fakat c2 de server e mesaj gönderdiğinden “input” değerini bekliyor. Sonra serverden gelen mesajı kabul ediyor ve ekrana yansıtıyor sorun bundan ibaret.
Merhaba, sorun galiba thread modülünde pek bir bilgim yok o modül hakkında. Attığınız kaynak ingilizce olduğundan pek bir şey anlamadım. Rica etsem olması gereken nedir kısaca anlatarak yazamırsınız?
En kaba tabiriyle söylemem gerekirse (Bilenler bizzat izah edeceklerdir) Parametre, bir fonksiyonun dışardan değer almasını sağlar ve içerisinde ona göre işlem yapar. Arguman, Parametre olarak yazdığın değer aslında.
Wormer_King’de size burda bunu göstermiş. Thread sınıfının args parametresini(argumanı ile) silerseniz yani
bu haliyle yazıp çalıştırmayı denerseniz hata aldığınızı görürsünüz. Çünkü oluşturulan fonksiyonda threadName adında bir parametre girilmiş ve o parametrenin alması gereken bir değere yani bir argumana ihtiyacı var. onu da Thread sınıfında args parametresi ile yapıyor.
Bir kaç eğitim videosu izledim ve biraz değişiklik yaptım fakat çok saçma ve garip oldu.
import socket
import threading
import time
host='192.168.56.1'
port=4444
addr=(host,port)
server=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("192.168.56.1:4444 numaralı port üzerinden sockete bağlanılıyor... # BY egecanlıTR")
server.connect(addr)
print("servere bağlanıldı")
def c_den_gelen_mesaj (conn):
while True:
conn=server.recv(50)
print(conn)
modül=threading.Thread(target=c_den_gelen_mesaj,args=("conn",))
modül.start()
def c_msg_gönder ():
while True:
msg_gönder=input("[CLİENT] MESAJ: ")
server.send(msg_gönder.encode())
time.sleep(0.5)
modül=threading.Thread(target=c_msg_gönder)
modül.start
c_msg_gönder()
Sorun hala devam ediyor fakat bu sefer önce 2. client mesaj attığında normal olarak servera mesajı gönderiyor ve bir daha input değeri soruyor, 2. input değeri istediğinde, 1. client mesaj attığında 1. clientten giden mesaj 2. cliente gidiyor ve input değerini girmediğim halde ekrana yazdırıyor fakat input değerini istediği yere yazıyor.
client herhangi bir değer yazamıyor bunu nasıl alta yazdırabilirim?
Port ve host’u saklama ihtiyacı hissetmişsiniz ama metni değiştirmeyi unutmuşsunuz sanırım. Gerçi bu bilgileri saklamanıza da gerek yok, 192.168.x.x formatındaki IP adresleri yerel ağınıza işaret ediyor.
Argüman alan fonksiyonlar tanımlamayı ve kullanmayı biliyor musunuz? Bana yürümeyi öğrenmeden koşmaya çalışıyormuşsunuz gibi geldi.
Bu yapmaya çalıştığınıza benzer bir sürü örnek daha önce paylaşılmıştı, buradan göz atabilirsiniz.
Maalesef, sizin attığınız kodda da benim çözmeye çalıştığım hata var. Clientler input değeri girmediği sürece c1 den gelen mesaj c2 ye aktarılmıyor bunuda thread modülü ile yapmamız lazm fakat nasıl?
Bunun sebebi input’un kod akışını bloklayan bir fonksiyon olması. Threading modülü ile bunu çözsek bile bu çözüm mevcut stdout ve stdin implementasyonuna bağlı olduğu için portatif olmaz. Girdi ve çıktı için bir arayüz kütüphanesi kullanmanız daha iyi olur.
Onu nasıl yapabilirim? Bu arada threading modülü ile tek yapmak istediğim “c_den_gelen_mesaj” fonksiyonu ile input komutunu aynı anda çalıştırmak. Bu ne kadar zor olabilir? sorusu kafamı karıştırıyor. Sizin önerdiğiniz çözümü biraz daha anlatır mısınız rica etsem
Zor değil ama büyük ihtimalle istediğiniz sonucu vermeyecek. Zaten konsoldan input alındığı esnada ekrana başka bir metin yazdırdığınızda ne olmasını bekliyorsunuz ki? input ve print fonksiyonları aynı anda çalıştırılmak için tasarlanan fonksiyonlar değil, her stdin ve stdout implementasyonu da böyle bir tasarımı desteklemek zorunda değil.
#paralel.py
import threading
def paralel_çalıştır(*fonksiyonlar):
threads = [threading.Thread(target = f) for f in fonksiyonlar]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
#client
import socket
from paralel import paralel_çalıştır
host='localhost'
port=4444
addr=(host,port)
server=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.connect(addr)
print("servere bağlanıldı")
def al():
while True:
msg_al=server.recv(50)
if msg_al == b"": # bağlantı koparsa boş metin döner
break
print(msg_al)
def gönder():
while True:
msg_gönder=input("[CLIENT] MESAJ: ")
server.send(msg_gönder.encode())
paralel_çalıştır(al, gönder)
Bu arada print ve input’un bu şekilde kullanımının thread safe olup olmadığı hakkında hiçbir şey göremedim ama GIL de göz önünde bulundurulunca thread safe’tir diye tahmin ediyorum.