Python ile hem input değeri beklerken hem de arkada nasıl işlem yapabilirim?

server:

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.

2 Beğeni

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?

Yapmanız gereken eşzamanlaı olarak hem input beklemek, hem de sunucuyu dinlemek.
Burası daha kolay bir şekilde anlatmış:

1 Beğeni

Modüldeki args= bölümüne ne yazmam gerektiğini anlayamıyorum.

Fonksiyonlara girdi olarak verilen argümanları oraya yazmanız gerekiyor.
Mesela adınızı yazdıran bir fonksiyonunuz olsun:

import threading

def calistir(threadName): 
    for i in range(7):
        print(threadName ," hoşgeldiniz")

t1 = threading.Thread(target=calistir, args = ("python", ))
t2 = threading.Thread(target=calistir, args = ("thread", ))

t1.start()
t2.start()
2 Beğeni

Kod da python diye bir argüman göremedim, Eminim çok iyi anlatıyorsunuzdur fakat bu işlerde daha yeniyim.

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

t1 = threading.Thread(target=calistir)
t2 = threading.Thread(target=calistir)

t1.start()
t2.start()

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.

1 Beğeni

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.

image

  1. client herhangi bir değer yazamıyor bunu nasıl alta yazdırabilirim?

Merhaba.

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.

Biliyorum, saklamama gerek yok. Fakat chat kanalıma bağlanmalarını istemiyordum. Beni deşifre etiğinize göre port numaramı değiştireyim :slight_smile:

Bu bilgiler ile buradaki kimse sizle bağlantı kuramaz, onu demek istemiştim:

1 Beğeni

Bu kod işinizi görüyor mu?

# server
import socket
import time
import threading

clients= {}
host='localhost'
port=4444
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(2)
print("1. Şahıs Dinleniyor...")
c,addr= server.accept()
print("1. Şahıs Bağlandı... {}".format(addr))

print("2. Şahıs Dinleniyor...")
c2,addr= server.accept()
print("2. Şahıs Bağlandı... {}".format(addr))

while True:
    mesaj=c.recv(50)
    print(mesaj)
    mesaj2=c2.recv(50)
    print(mesaj2)

    c2.send(mesaj)
    c.send(mesaj2)
#client
import socket
import threading

import time


host='localhost'
port=4444
addr=(host,port)
server=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.connect(addr)

print("servere bağlanıldı")

while True:
    msg_gönder=input("[CLIENT] MESAJ: ")

    server.send(msg_gönder.encode())

    msg_al=server.recv(50)
    if msg_al == b"": # bağlantı koparsa boş metin döner
            break
    print(msg_al)

1 Beğeni

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?

Thread modülü ile yapmak istediğinizde nasıl yapardınız?

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.

1 Beğeni

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

Tkinter gibi bir kütüphane kullanabilirsiniz.

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()
#server.py
import socket
from paralel import paralel_çalıştır

clients= {}
host='localhost'
port=4444
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(2)
print("1. Şahıs Dinleniyor...")
c,addr= server.accept()
print("1. Şahıs Bağlandı... {}".format(addr))

print("2. Şahıs Dinleniyor...")
c2,addr= server.accept()
print("2. Şahıs Bağlandı... {}".format(addr))

def ilet(c, c2):
    def inner():
        while True:
            mesaj=c.recv(50)
            print(mesaj.decode())
            c2.send(mesaj)
    return inner
    
paralel_çalıştır(ilet(c, c2), ilet(c2, c))
#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.

3 Beğeni

Paralel modülünü bilmiyordum. Araştırmak istiyorum, Teşekkürler.

Paralel modülü, oluşturulan paralel.py dosyasıdır.

2 Beğeni