Python Socket Ve Threading Kaynak Bilen Var mı?

Arkadaşlar Threading İle İlgili Kaynaklar Bilen Var mı? Türkçe Olsun Lütfen…Öz Ve Güzel Anlatım Olursa Bide İyi Olur.Birde Socket Kaynağı Lazım…Bu 2sini Çok Merak Ediyorum…

Günceldir.Lütfen Görenler Yazsın.

Merhaba.

Google’da arama yaptınız mı? Yaptıysanız, orada bulduğunuz kaynaklardaki eksikler nelerdi? Belki de bu noktalara odaklanmalıyız.

İyi çalışmalar.

Yaptım Hocam Lakin Çok Karmaşık Geldi Bana Zaten 2-3 Kaynak Bulabildim Mesela Threading İle…Socket İle Bulduğum Kaynaktada 2.7 İçindi Ve Hatalar Vardı Kodların Aynısını Deneyince Hata Veriyordu…

Belki bulduklarınız arasındadır ama Yasar Arabacı’nın bir yazısı var.Onu okuyun.
http://ysar.net/python/threading.html
Yazıyı anlayamadıydanız:

from Tkinter import Button
from Tkinter import Label
import tkinter
import threading
import time

degistir = False      #butona bastigimda degeri degisecek

def butona_basildiginda():     #butona basıldığında yapılacakları tanımladım
    global degistir    #global onemli nokta yoksa error verir
    degistir = True

def arka_plan():    #arkaplanda yapmak istediklerim
    global degistir
    while True:
        if not degistir:
            print("arkaplanda calisiyorum")   #eger butona basılmamıssa arkaplanda calısmaya devam ediyorum bastır
        else:
            print("arkaplanda calismayi kesiyorum.cunku butonuma bastilar") #butona basıldıgında yapılacaklar
            time.sleep(5)
            break

thread_part = threading.Thread(target = arka_plan) #arka_plan adlı fonksiyonu thread e emanet edecegiz onun icin ilk olarak Thread sinifi tanimla
thread_part.daemon = True #daemonu True yap
thread_part.start() #fonksiyon arkaplanda calısmaya baslasın( siz de baska islerinize odaklanın boylece:))

pcr = Tkinter.Tk()

etk = Label(text="!!!ornektir!!!")
etk.pack()

bttn = Button(text="bas bana arkada calisan fonksiyonu durdurayim",command = butona_basildiginda)
bttn.pack()

pcr.mainloop()

Anlasılmasi acısından bir de burada yaptiklarimi threading modulunu kullanmadan deneyebilirsiniz.
Ayriyeten:

import threading 
response = None 
def user_input(): 
    global response 
    response = input("Do you wish to reconnect? ") 

user = threading.Thread(target=user_input) 
user.daemon = True
user.start() 
user.join(10)
if response is None: 

    print('Exiting') 
else: 
    print('As you wish')

kullanicidan 10 saniye input bekleyip 10 saniye doldugunda cevap yoksa Exiting bastiran kod parcası.Belki isinize yarar.

Socket e gelince;
Maalesef,socket modulunu kullanmayi bilmiyorum(cunku su ana kadar ihtiyac duymadım ama yakında incelerim.)

Kodları python3 e gore yeniden uyarlamayi denediniz mi?

1 Beğeni

Yaşar Hocam Yeni Başlayanlar İçin Değilde Sanki Threading’i Bilenler İçin Anlatmış Gibi Karışık…

thread kavramı dilden bağımsız bir kavramdır işletim sistemlerinin verdiği olanaklardır
Sayın Kaan Aslan’ın anlatımı https://www.youtube.com/watch?v=SaCcYVWp2bw
Şadi evren Şeker’in anlatımı https://www.youtube.com/watch?v=-BbRdNwRghg

1 Beğeni

Merhaba, socket ve threading’in birlikte kullanımı için aşağıdaki örneği inceleyebilirsiniz:

server.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import time
from datetime import datetime
import socket
import threading
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk


# Uygulama için gerekli Tkinter widgetlerini oluşturalım.
root = tk.Tk()
root.title("Server")

text = tk.Text(master=root)
text.pack(expand=True, fill="both")

entry = tk.Entry(master=root)
entry.pack(expand=True, fill="x")

frame = tk.Frame(master=root)
frame.pack()


def buttons():
    for i in "Connect", "Send", "Clear", "Disconnect", "Exit":
        b = tk.Button(master=frame, text=i)
        b.pack(side="left")
        yield b


b1, b2, b3, b4, b5 = buttons()


# Şimdi socket modülünden bir sunucu nesnesi oluşturalım ve bu nesnenin
# özelliklerini oluşturalım.
class Server:
    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.__c = None
        # Yukarıdaki self.__c aşağıda condition() kısmında
        # tanımlanan döngüyü sonlandırmak için lazım olacak.

    @property
    def c(self):
        return self.__c

    @c.setter
    def c(self, c):
        self.__c = c

    @c.deleter
    def c(self):
        del self.__c

    def connect(self):
        """connect fonksiyonu çağrılırsa aşağıdaki
        işlemleri yerine getirir."""
        self.s.bind(("", 12345))
        self.s.listen(10)
        now = str(datetime.now())[:-7]
        text.insert("insert", "Date: {}\nConnected.\n".format(now))
        c, addr = self.s.accept()
        text.insert("insert", "Date: {}\n{} connected.\n".format(str(datetime.now())[:-7], addr))
        self.__c = c
        self.condition()

    def condition(self):
        """Döngü self.__c None olmadığı sürece devam eder."""
        while self.__c is not None:
            data = str(self.__c.recv(1024))[1:]
            now = str(datetime.now())[:-7]
            text.insert("insert", "\nDate: {}\nClient: {}\n".format(now, data))
            time.sleep(2)

    def send(self):
        """Mesaj gönderme fonksiyonunu tanımlayalım."""
        respond = str(entry.get())
        self.__c.sendall(bytes(respond.encode("utf-8")))
        now = str(datetime.now())[:-7]
        entry.delete("0", "end")
        text.insert("insert", "\nDate: {}\nServer: {}\n".format(now, respond))


# Şimdi nesnemizden bir örnek oluşturalım.
s1 = Server()


# Düğmelere basınca çalışacak fonksiyonları oluşturalım.
def connect():
    """Programın çalışan diğer parçaları bu iş yükünden etkilenmesin
    diye, bu dinleme işlemini bir iş parçacığına dönüştürmemiz gerekiyor."""
    t1 = threading.Thread(target=s1.connect)
    t1.start()


def send():
    """Bu fonksiyon çağrılırsa, socket nesnesinin mesaj gönderme işlemini
    bir iş parçacığına dönüştürür."""
    t2 = threading.Thread(target=s1.send)
    t2.start()


def clear():
    """Bu fonksiyon çağrılırsa yazıların aktarıldığı ekran temizlenir."""
    text.delete("1.0", "end")


def accept_again():
    """"Bu fonksiyon istemci sunucudan koptuktan sonra onun tekrar bağlanmasını sağlar."""
    s1.c, addr = s1.s.accept()  # s1.c ve addr değişkenlerini yeniden tanımlamak gerekiyor.
    text.insert("insert", "Date: {}\n{} connected.\n".format(str(datetime.now())[:-7], addr))
    s1.condition()  # istemciden gelen mesajları görebilmek için tekrar döngüyü devreye sokmak gerekiyor.


def disconnect():
    """Bu fonksiyon çağrılırsa; istemcinin uygulaması kapatıldıktan sonra,
    sunucu ekrana yazı bastırılmasını önlemek için while döngüsünü
    sonlandıracak olan değişkende değişiklik yapar. Ve istemci tekrar sunucuya
    bağlanmak isterse, sunucu tarafından tekrar kabul edilmesini sağlar."""
    s1.c = None  # condition() fonksiyonunu sonlandırır.
    t3 = threading.Thread(target=accept_again)  # istemcinin tekrar bağlanması için bir accept_again()
    t3.start()                                  # fonksiyonunu bir iş parçacığına dönüştürelim.                                 


def destroy():
    """Bu fonksiyon çağrılırsa tkinter uygulaması sonlanır."""
    root.destroy()


# Düğmelerin yapacakları işleri belirleyelim.
b1.configure(command=connect)
b2.configure(command=send)
b3.configure(command=clear)
b4.configure(command=disconnect)
b5.configure(command=destroy)

# Tkinter uygulamasını da bir iş parçacağına dönüştürelim.
t0 = threading.Thread(target=root.mainloop)
# Ve onu run() metoduyla sürekli çalışır halde olacak şekilde ayarlayalım.
t0.run()

client.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import time
from datetime import datetime
import socket
import threading
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk


# Uygulama için gerekli Tkinter widgetlerini oluşturalım.
root = tk.Tk()
root.title("Client")

text = tk.Text(master=root)
text.pack(expand=True, fill="both")

entry = tk.Entry(master=root)
entry.pack(expand=True, fill="x")

frame = tk.Frame(master=root)
frame.pack()


def buttons():
    for i in "Connect", "Send", "Clear", "Disconnect", "Exit":
        b = tk.Button(master=frame, text=i)
        b.pack(side="left")
        yield b


b1, b2, b3, b4, b5 = buttons()


# Şimdi socket modülünden bir istemci nesnesi oluşturalım ve bu nesnenin
# özelliklerini oluşturalım.
class Client:
    def __init__(self):
        self.__s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # Yukarıdaki self.__s aşağıda condition() kısmında
        # tanımlanan döngüyü sonlandırmak için lazım olacak.

    @property
    def s(self):
        return self.__s

    @s.deleter
    def s(self):
        del self.__s

    @s.setter
    def s(self, s):
        self.__s = s

    def connect(self):
        """connect fonksiyonu çağrılırsa aşağıdaki
        işlemleri yerine getirir."""
        self.__s.connect(("", 12345))
        now = str(datetime.now())[:-7]
        text.insert("insert", "Date: {}\nConnected.\n".format(now))
        self.condition()

    def condition(self):
        """Döngü self.__s None olmadığı sürece devam eder."""
        while self.__s is not None:
            data = str(self.__s.recv(1024))[1:]
            now = str(datetime.now())[:-7]
            text.insert("insert", "\nDate: {}\Server: {}\n".format(now, data))
            time.sleep(2)

    def send(self):
        """Mesaj gönderme fonksiyonunu tanımlayalım."""
        respond = str(entry.get())
        now = str(datetime.now())[:-7]
        self.__s.sendall(bytes(respond.encode("utf-8")))
        entry.delete("0", "end")
        text.insert("insert", "\nDate: {}\nClient: {}\n".format(now, respond))


# Şimdi nesnemizden bir örnek oluşturalım.
c1 = Client()


# Düğmelere basınca çalışacak fonksiyonları oluşturalım.
def connect():
    """Programın çalışan diğer parçaları bu iş yükünden etkilenmesin
    diye, bu dinleme işlemini bir iş parçacığına dönüştürmemiz gerekiyor."""
    t1 = threading.Thread(target=c1.connect)
    t1.start()


def send():
    """Bu fonksiyon çağrılırsa, socket nesnesinin mesaj gönderme işlemini
    bir iş parçacığına dönüştürür."""
    t2 = threading.Thread(target=c1.send)
    t2.start()


def clear():
    """Bu fonksiyon çağrılırsa yazıların aktarıldığı ekran temizlenir."""
    text.delete("1.0", "end")


def disconnect():
    """Bu fonksiyon çağrılırsa; sunucunun uygulaması kapatıldıktan sonra,
    istemci ekrana yazı bastırılmasını önlemek için while döngüsünü
    sonlandıracak olan değişkende değişiklik yapar."""
    c1.s = None


def destroy():
    """Bu fonksiyon çağrılırsa tkinter uygulaması sonlanır."""
    root.destroy()


# Düğmelerin yapacakları işleri belirleyelim.
b1.configure(command=connect)
b2.configure(command=send)
b3.configure(command=clear)
b4.configure(command=disconnect)
b5.configure(command=destroy)

# Tkinter uygulamasını da bir iş parçacağına dönüştürelim.
t0 = threading.Thread(target=root.mainloop)
# Ve onu run() metoduyla sürekli çalışır halde olacak şekilde ayarlayalım.
t0.run()

Hocam Pek Tkinter Kullanmadım Ve Sınıf Karışık Geldi Biraz :smiley:

Sizinle daha basit bir örnek paylaşayım o zaman; program açıkken server ve client arasında eş zamanlı mesaj alışverişi yapabilirsiniz ancak server veya client ikisinden birisi oturumu kapatırsa, oturumu kapanmamış programda, while döngüsünden ötürü, istemciden gelen boş mesajlar ekrana bastırılır ve program sonunda RuntimeError hatası verir. Bu sorunu daha gideremedim. Ama giderirsem programa ekleme yaparım.

server.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket
import threading

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", 12345))
s.listen(10)
print(s)

c, addr = s.accept()
print('{} bağlandı.'.format(addr))


def receive():
    data = str(c.recv(1024))[1:]
    print("\nİstemci: {}".format(data))


def send():
    global c
    respond = input("Sunucu: ").encode("utf-8")
    c.sendall(bytes(respond))


while True:
    t_receive = threading.Thread(target=receive)
    t_send = threading.Thread(target=send)
    t_send.start()
    t_receive.daemon = True
    t_receive.start()
    t_receive.join(1)

client.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket
import threading

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("", 12345))


def receive():
    data = str(s.recv(1024))[1:]
    print("\nSunucu: {}\n".format(data))


def send():
    respond = input("İstemci: ").encode("utf-8")
    s.sendall(bytes(respond))


while True:
    t_receive = threading.Thread(target=receive)
    t_send = threading.Thread(target=send)
    t_receive.start()
    t_send.daemon = True
    t_send.start()
    t_send.join(1)

Boş mesaj sorunu için threading kullanılamıyor maalesef ya da ben beceremdim internetteki kaynaklarda da threading kullanmamışlar onun yerine select modülü kullanılıyor. burada daha detaylı bilgi var incelenirse anlaşılabilir.

socket ve threading’i tkinter ile birlikte kullanınca, sunucu veya istemci ikisinden birisi oturumu terk ederse, disconnect isimli bir düğme sayesinde, döngüyü sonlandırabiliyoruz (Sunucu açık kaldığı sürece istemci tekrar tekrar sunucuya bağlanabilir.). Çünkü tuşlar sayesinde döngüyü kontrol etme şansımız oluyor. Ama diğer programda döngüyü nasıl kontrol edeceğimi bulamadım daha.

Merhaba.

Belki bu problem istemci ya da sunucu kapatıldığında birbirlerine özel bir mesaj göndermeleri yoluyla çözülebilir. Teoride istemcinin kapatılmasının sunucuyu etkilememesi gerek. Çünkü birden fazla istemci aynı anda var olabilir. Ancak sunucu kapandığında istemciler yanıt alamayacakları için kullanıcıya hata göstermeleri normal. Sonrasında gerçeklemeye göre istemci kullanıcının tekrar bağlanmasını isteyebilir ya da sunucu tekrar çevrimiçi olduğunda otomatik olarak bağlanabilir.

İyi çalışmalar.

Tekrar merhaba.

Yukarıdaki her iki örnekte de aslında sunucu istemcinin bağlantısının koptuğundan ancak şu şekilde haberdar oluyor: İstemci sunucudan koparsa, istemciden boş mesajlar sürekli sunucuya gelmeye başlıyor, ta ki threading’den kaynaklanan RuntimeError hatası yükseltilene kadar.

tkinter, socket ve threading kullanılan ilk örnekte, istemciden gelen boş mesajları engelleyecek disconnect isimli bir tuş tanımlandı. Böylece istemci sunucudan koparsa, sunucudaki kişi de istemciden boş mesajlar geldiğini fark ederse, disconnect tuşuna basıp bu boş mesajların gelmesini engelleyebilir. Disconnect tuşunda ayrıca accept_again() isimli başka bir fonksiyon tanımlandığı için de, istemci daha sonradan sunucuya tekrar bağlanabilir. Bu tuş tanımlanmazsa istemci tekrar sunucuya bağlanamaz.

Ama sadece socket ve threading kullanılan örnekte, istemciden gelen boş mesajları engelleyecek bir uyarı sistemini oluşturamadım henüz, yani denedim ama olmadı.

Dediğinizi ben de düşündüm, ancak sunucu, istemcinin bağlantısının koptuğunu ekranına boş mesajlar gelmeden nasıl anlayacak onu bulamadım. Yani diyelim istemci konsol uygulamasını direk sağ veya sol üst köşedeki çarpı tuşuna basarak sonlandırdı ve sunucunun ekranına birden hızlı bir şekilde boş mesajlar gelmeye başladı. Bu durumda sunucuya, istemcinin koptuğuna dair, istemciden bir bilgi gönderilemez.

GUI uygulamasında bu durumu tuşlarla önlemek daha kolay. Çünkü tuş yardımıyla, socket sınıfından oluşturulan değişkeni değiştirip, döngünün sonlanmasını sağlayabiliriz.

Belki daha farklı bir bakış açısı ile program değiştirilebilir ve uyarı sistemi programa dahil edilebilir bilemiyorum ama, şu haliyle programda istediğim değişikliği yapamıyorum.

Tekrar merhaba.

Sorunun çözümünü buldum. Daha önceleri, gelen boş string verisinin uzunluğu 0 ise ekrana yazının bastırılmamasını sağlayan bir ekleme yapmıştım ama istediğim sonucu alamamıştım. Ama sonra ekrana gelen stringlerin uzunluğunu merak ettim ve gördüm ki bir string boşken uzunluğu 2 oluyor veya sadece bir elemanı olan bir stringin uzunluğu 3 oluyor… Bu duruma göre programda değişiklik yaptım ve şimdi program istenildiği gibi çalışır hale geldi. Aynı değişiklik, bu programın GUI uygulamasında da yapılıp, disconnect tuşu devre dışı bırakılabilir.

Kodlar:

server.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket
import threading


class Server:
    clients = []

    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.c = None

    def connect(self):
        self.s.bind(("", 12345))
        self.s.listen(10)
        print(self.s)

    def accept(self):
        try:
            c, addr = self.s.accept()
            self.c = c
            print('{} connected.'.format(addr))
            self.clients.append(c)
        except OSError:
            pass

    def receive(self):
        if self.c is not None:
            data = str(self.c.recv(1024))[1:]
            if len(data) == 2:
                pass
            else:
                print("\nClient: {}".format(data))

    def send(self):
        try:
            if self.c is not None:
                respond = input("Server: ").encode("utf-8")
                for i in self.clients:
                    i.send(bytes(respond))
        except BrokenPipeError:
            print("\nClient has been disconnected\n")


s1 = Server()
t0 = threading.Thread(target=s1.connect)
t0.start()

while True:
    t1 = threading.Thread(target=s1.accept)
    t1.daemon = True
    t1.start()
    t1.join(1)
    t2 = threading.Thread(target=s1.send)
    t2.start()
    t3 = threading.Thread(target=s1.receive)
    t3.daemon = True
    t3.start()
    t3.join(1)

client.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket
import threading


class Client:
    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    def connect(self):
        self.s.connect(("", 12345))

    def receive(self):
        data = str(self.s.recv(1024))[1:]
        if len(data) == 2:
            pass
        else:
            print("\nServer: {}".format(data))

    def send(self):
        respond = input("Client: ").encode("utf-8")
        self.s.sendall(bytes(respond))


c1 = Client()
t0 = threading.Thread(target=c1.connect)
t0.start()
while True:
    t1 = threading.Thread(target=c1.receive)
    t1.start()
    t2 = threading.Thread(target=c1.send)
    t2.daemon = True
    t2.start()
    t2.join(1)
1 Beğeni

Bu uygulamanın GUI versiyonu da aşağıdaki gibi olur:

server.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import time
from datetime import datetime
import socket
import threading
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk


# Uygulama için gerekli Tkinter widgetlerini oluşturalım.
root = tk.Tk()
root.title("Server")

text = tk.Text(master=root)
text.pack(expand=True, fill="both")

entry = tk.Entry(master=root)
entry.pack(expand=True, fill="x")

frame = tk.Frame(master=root)
frame.pack()


def buttons():
    for i in "Connect", "Send", "Clear", "Exit":
        b = tk.Button(master=frame, text=i)
        b.pack(side="left")
        yield b


b1, b2, b3, b4 = buttons()


# Şimdi socket modülünden bir sunucu nesnesi oluşturalım ve bu nesnenin
# özelliklerini oluşturalım.
class Server:
    clients = []

    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.c = None

    def connect(self):
        """connect fonksiyonu çağrılırsa aşağıdaki
        işlemleri yerine getirir."""
        self.s.bind(("", 12346))
        self.s.listen(10)
        now = str(datetime.now())[:-7]
        text.insert("insert", "Date: {}\nConnected.\n".format(now))
        self.condition()

    def accept(self):
        c, addr = self.s.accept()
        text.insert("insert", "Date: {}\n{} connected.\n".format(str(datetime.now())[:-7], addr))
        self.c = c
        self.clients.append(c)

    def receive(self):
        if self.c is not None:
            data = str(self.c.recv(1024))[1:]
            now = str(datetime.now())[:-7]
            if len(data) == 2:
                pass
            else:
                text.insert("insert", "\nDate: {}\nClient: {}\n".format(now, data))
                time.sleep(2)

    def condition(self):
        while True:
            t11 = threading.Thread(target=self.accept)
            t11.daemon = True
            t11.start()
            t11.join(1)
            t12 = threading.Thread(target=self.receive)
            t12.daemon = True
            t12.start()
            t12.join(1)

    def send(self):
        """Mesaj gönderme fonksiyonunu tanımlayalım."""
        respond = str(entry.get())
        now = str(datetime.now())[:-7]
        entry.delete("0", "end")
        try:
            for i in self.clients:
                i.sendall(bytes(respond.encode("utf-8")))
            text.insert("insert", "\nDate: {}\nServer: {}\n".format(now, respond))
        except BrokenPipeError:
            text.insert("insert", "\nDate: {}\nİstemci koptu.\n".format(now))


# Şimdi nesnemizden bir örnek oluşturalım.
s1 = Server()


# Düğmelere basınca çalışacak fonksiyonları oluşturalım.
def connect():
    """Programın çalışan diğer parçaları bu iş yükünden etkilenmesin
    diye, bu dinleme işlemini bir iş parçacığına dönüştürmemiz gerekiyor."""
    t1 = threading.Thread(target=s1.connect)
    t1.start()


def send():
    """Bu fonksiyon çağrılırsa, socket nesnesinin mesaj gönderme işlemini
    bir iş parçacığına dönüştürür."""
    t2 = threading.Thread(target=s1.send)
    t2.start()


def clear():
    """Bu fonksiyon çağrılırsa yazıların aktarıldığı ekran temizlenir."""
    text.delete("1.0", "end")


def destroy():
    """Bu fonksiyon çağrılırsa tkinter uygulaması sonlanır."""
    root.destroy()


# Düğmelerin yapacakları işleri belirleyelim.
b1.configure(command=connect)
b2.configure(command=send)
b3.configure(command=clear)
b4.configure(command=destroy)

# Tkinter uygulamasını da bir iş parçacağına dönüştürelim.
t0 = threading.Thread(target=root.mainloop)
# Ve onu run() metoduyla sürekli çalışır halde olacak şekilde ayarlayalım.
t0.run()

client.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import time
from datetime import datetime
import socket
import threading
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk


# Uygulama için gerekli Tkinter widgetlerini oluşturalım.
root = tk.Tk()
root.title("Client")

text = tk.Text(master=root)
text.pack(expand=True, fill="both")

entry = tk.Entry(master=root)
entry.pack(expand=True, fill="x")

frame = tk.Frame(master=root)
frame.pack()


def buttons():
    for i in "Connect", "Send", "Clear", "Exit":
        b = tk.Button(master=frame, text=i)
        b.pack(side="left")
        yield b


b1, b2, b3, b4 = buttons()


# Şimdi socket modülünden bir istemci nesnesi oluşturalım ve bu nesnenin
# özelliklerini oluşturalım.
class Client:
    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    def connect(self):
        """connect fonksiyonu çağrılırsa aşağıdaki
        işlemleri yerine getirir."""
        self.s.connect(("", 12346))
        now = str(datetime.now())[:-7]
        text.insert("insert", "Date: {}\nConnected.\n".format(now))
        self.receive()

    def receive(self):
        """Mesaj alma fonksiyonunu tanımlayalım."""
        while True:
            data = str(self.s.recv(1024))[1:]
            now = str(datetime.now())[:-7]
            if len(data) == 2:
                pass
            else:
                text.insert("insert", "\nDate: {}\nServer: {}\n".format(now, data))
                time.sleep(2)

    def send(self):
        """Mesaj gönderme fonksiyonunu tanımlayalım."""
        respond = str(entry.get())
        now = str(datetime.now())[:-7]
        entry.delete("0", "end")
        try:
            self.s.sendall(bytes(respond.encode("utf-8")))
            text.insert("insert", "\nDate: {}\nClient: {}\n".format(now, respond))
        except BrokenPipeError:
            text.insert("insert", "\nDate: {}\nSunucu koptu.\n".format(now))
            self.s.close()


# Şimdi nesnemizden bir örnek oluşturalım.
c1 = Client()


# Düğmelere basınca çalışacak fonksiyonları oluşturalım.
def connect():
    """Programın çalışan diğer parçaları bu iş yükünden etkilenmesin
    diye, bu dinleme işlemini bir iş parçacığına dönüştürmemiz gerekiyor."""
    t1 = threading.Thread(target=c1.connect)
    t1.start()


def send():
    """Bu fonksiyon çağrılırsa, socket nesnesinin mesaj gönderme işlemini
    bir iş parçacığına dönüştürür."""
    t2 = threading.Thread(target=c1.send)
    t2.start()


def clear():
    """Bu fonksiyon çağrılırsa yazıların aktarıldığı ekran temizlenir."""
    text.delete("1.0", "end")


def destroy():
    """Bu fonksiyon çağrılırsa tkinter uygulaması sonlanır."""
    root.destroy()


# Düğmelerin yapacakları işleri belirleyelim.
b1.configure(command=connect)
b2.configure(command=send)
b3.configure(command=clear)
b4.configure(command=destroy)

# Tkinter uygulamasını da bir iş parçacağına dönüştürelim.
t0 = threading.Thread(target=root.mainloop)
# Ve onu run() metoduyla sürekli çalışır halde olacak şekilde ayarlayalım.
t0.run()
1 Beğeni

Yukarıdaki her iki program da socket ve threading’in birlikte nasıl kullanılabileceğini gösteren basit örneklerdir.

Her iki program da, birden çok istemcinin bir sunucuya bağlanmasına olanak sağlar. Ancak her iki programda da sunucu, kendisine bağlanan istemcilerden hangisine mesaj göndermesi gerektiğini ayırt edemez (Sunucunun mesajı, son bağlanan istemciye gönderilir. Buna karşın, bütün istemcilerin mesajları sunucuya gönderilir… ). Bu sorunu çözmek için her iki programa da eklemeler yapmak gerekiyor. Bu sorun ile ilgili tavsiyesi olan arkadaşlar tavsiyelerini esirgemezlerse sevinirim.

Edit: Bu mesajda belirtilen sorun da çözülmüştür ve yukarıdaki kodlarda gerekli değişiklikler yapılmıştır. Artık sunucunun gönderdiği mesajlar bütün istemcilere ulaşır. Eğer sunucunun sadece bir istemciye özel bir mesaj göndermesini, başka bir istemcinin de bu sunucu mesajını görmemesini istiyorsak programda değişiklikler yapmak lazım. Onu da yaparsak programı biraz daha geliştirmiş oluruz. Sonra belki tasarım üzerinde biraz değişiklik yapılır, program biraz daha geliştirilmiş olur. Sonra belki başka bir özelliğe gerek duyulur, programa eklemeler çıkartmalar yapılması gerekir, sonuç olarak program geliştirme süreci kaldığı yerden devam eder.

Programda ufak bir değişiklik yapıldı. Sunucu, artık kendisine gönderilen mesajların kimden geldiğini görebilir. Yeni kodlar, aşağıdadır:

server.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from datetime import datetime
import socket
import threading
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk


root = tk.Tk()
root.title("Server")

text = tk.Text(master=root)
text.pack(expand=True, fill="both")

entry = tk.Entry(master=root)
entry.pack(expand=True, fill="x")

frame = tk.Frame(master=root)
frame.pack()


def buttons():
    for i in "Connect", "Send", "Clear", "Exit":
        b = tk.Button(master=frame, text=i)
        b.pack(side="left")
        yield b


b1, b2, b3, b4, = buttons()


class Server:
    clients = []

    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    def connect(self):
        self.s.bind(("", 12346))
        self.s.listen(10)
        now = str(datetime.now())[:-7]
        text.insert("insert", "({}) : Connected.\n".format(now))
        self.condition()

    def accept(self):
        c, addr = self.s.accept()
        self.clients.append(c)
        data = c.recv(1024)
        text.insert("insert", "({}) : {} connected.\n".format(str(datetime.now())[:-7], str(data)[1:]))

    def receive(self):
        for i in self.clients:

            def f():
                data = str(i.recv(1024))[2:-1]
                now = str(datetime.now())[:-7]
                if len(data) == 0:
                    pass
                else:
                    text.insert("insert", "({}) : {}\n".format(now, data))

            t1_2_1 = threading.Thread(target=f)
            t1_2_1.start()

    def condition(self):
        while True:
            t1_1 = threading.Thread(target=self.accept)
            t1_1.daemon = True
            t1_1.start()
            t1_1.join(1)
            t1_2 = threading.Thread(target=self.receive)
            t1_2.daemon = True
            t1_2.start()
            t1_2.join(1)

    def send(self):
        respond = "Server: {}".format(str(entry.get()))
        now = str(datetime.now())[:-7]
        entry.delete("0", "end")
        try:
            for i in self.clients:
                i.sendall(bytes(respond.encode("utf-8")))
            text.insert("insert", "({}) : {}\n".format(now, respond))
        except BrokenPipeError:
            text.insert("insert", "({}) : Client has been disconnected.\n".format(now))


s1 = Server()


def connect():
    t1 = threading.Thread(target=s1.connect)
    t1.start()


def send():
    t2 = threading.Thread(target=s1.send)
    t2.start()


def clear():
    text.delete("1.0", "end")


def destroy():
    root.destroy()
    exit()


if __name__ == "__main__":
    b1.configure(command=connect)
    b2.configure(command=send)
    b3.configure(command=clear)
    b4.configure(command=destroy)
    t0 = threading.Thread(target=root.mainloop)
    t0.run()

client.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from datetime import datetime
import socket
import threading
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk


root = tk.Tk()
root.title("Client")

text = tk.Text(master=root)
text.pack(expand=True, fill="both")

entry = tk.Entry(master=root)
entry.pack(expand=True, fill="x")

frame = tk.Frame(master=root)
frame.pack()


def buttons():
    for i in "Connect", "Create A Nickname", "Send", "Clear", "Exit":
        b = tk.Button(master=frame, text=i)
        b.pack(side="left")
        yield b


b1, b2, b3, b4, b5 = buttons()


class Client:
    def __init__(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.nickname = None

    def connect(self):
        now = str(datetime.now())[:-7]
        if self.nickname is not None:
            try:
                self.s.connect(("", 12346))
                text.insert("insert", "({}) : Connected.\n".format(now))
                self.s.sendall(bytes("{}".format(self.nickname).encode("utf-8")))
                self.receive()
            except ConnectionRefusedError:
                text.insert("insert", "({}) : The server is not online.\n".format(now))
        else:
            text.insert("insert", "({}) : You must create a nickname.\n".format(now))

    def receive(self):
        while True:
            data = str(self.s.recv(1024))[2:-1]
            now = str(datetime.now())[:-7]
            if len(data) == 0:
                pass
            else:
                text.insert("insert", "({}) : {}\n".format(now, data))

    def do_nothing(self):
        pass

    def create_nickname(self):
        b2.configure(command=self.do_nothing)
        _frame = tk.Frame(master=root)
        _frame.pack()
        new_entry = tk.Entry(master=_frame)
        new_entry.grid(row=0, column=0)
        new_button = tk.Button(master=_frame, text="Accept Your Nickname")
        new_button.grid(row=1, column=0)

        def nickname_command():
            now = str(datetime.now())[:-7]
            if new_entry.get() == "":
                text.insert("insert", "({}) : You must write a nickname.\n".format(now))
            else:
                self.nickname = new_entry.get()
                _frame.destroy()
                text.insert("insert", "({}) : Nickname has changed to: '{}'\n".format(now, self.nickname))
                b2.configure(command=c1.create_nickname)

        new_button.configure(command=nickname_command)

    def send(self):
        respond = "{}: {}".format(self.nickname, str(entry.get()))
        now = str(datetime.now())[:-7]
        entry.delete("0", "end")
        try:
            self.s.sendall(bytes(respond.encode("utf-8")))
            text.insert("insert", "({}) : {}\n".format(now, respond))
        except BrokenPipeError:
            text.insert("insert", "({}) : Server has been disconnected.\n".format(now))
            self.s.close()


c1 = Client()


def connect():
    t1 = threading.Thread(target=c1.connect)
    t1.start()


def send():
    t2 = threading.Thread(target=c1.send)
    t2.start()


def clear():
    text.delete("1.0", "end")


def destroy():
    root.destroy()


if __name__ == "__main__":
    b1.configure(command=connect)
    b2.configure(command=c1.create_nickname)
    b3.configure(command=send)
    b4.configure(command=clear)
    b5.configure(command=destroy)
    t0 = threading.Thread(target=root.mainloop)
    t0.run()

Edit: Program şu haliyle istendiği gibi çalışmamaktadır. Sorun şu ki, bir istemcinin gönderdiği mesaj, ancak diğer istemci de mesaj gönderdiği zaman sunucu ekranına bastırılıyor. Halbuki ilk bağlanan istemcinin mesajı sorunsuz bir şekilde sunucu ekranında gösteriliyor. Sorunun sunucudaki for döngüsünden kaynaklandığını düşünüyorum. Bir çözüm bulursam bu mesajı tekrar düzenlerim.

Edit: Sandığımdan fazla sorun varmış.

Edit: Yukarıda bahsedilen sorunlar çözüldü. Kodlar yenilenmiştir.

1 Beğeni

Tekrar merhaba.

Programa yeni bir özellik eklendi. Bu özellikle birlikte, artık sunucu, kendisine bağlanan istemcilere ayrı ayrı mesaj gönderebilir.

Aşağıda, programın nasıl çalıştığını adım adım resimlerden takip edebilirsiniz.

  1. Önce server.py dosyasını çalıştırıyoruz.

Sağ tarafta görülen “Client Connections” kısmında şuanlık hiç bir istemci görünmemektedir.

  1. Şimdi sunucuyu internete bağlayalım.

Sunucu, istemcilerin kendisine bağlanmasını bekleyedursun.

  1. Şimdi client.py dosyasını çalıştıralım.

3

  1. İstemciye bir kullanıcı adı vermeden, sunucuya bağlanamayız.

4

  1. Kullanıcı adını sadece bir kereliğine verebiliriz ve kullanıcı adı boş bırakılamaz.

5

  1. Kullanıcı adını belirliyoruz ve aşağı doğru açılmış olan nickname bölümü ortadan kayboluyor ve “Client” olan programın ismi belirlenen kullanıcı adı olarak değişiyor.

6

  1. Şimdi sunucuya bağlanabiliriz.

7

  1. İstemci sunucuya bağlanır bağlanmaz sunucu ekranının sağ tarafında istemcinin ismi, bir yazı yazma girişi ve yazıyı göndermek için bir tuş oluşturulur.

  1. “Ahmet” isminde yeni bir istemci daha oluşturalım ve onu da sunucuya bağlayalım.

9

  1. Sunucu ekranına bir daha bakalım:

  1. Şimdi Ali’ye ve Ahmet’e ayrı ayrı mesajlar gönderelim.

  1. İstemci sunucudan düşerse, sunucunun ekranının sağ tarafındaki istemciye ait isim bilgisi, yazı yazma girişi ve tuş da otomatik olarak silinir.

Kodlar:

server.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket
import threading
from datetime import datetime
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk

root = tk.Tk()
root.title("Server")
right_frame = tk.Frame(master=root)
right_frame.pack(side="right", fill="y", expand=True)
right_frame_label = tk.Label(master=right_frame, text="Client Connections", width=78, bd=1, relief="sunken")
right_frame_label.pack(side="top", fill="x")
text = tk.Text(master=root, state="disabled")
text.pack(expand=True, fill="both")
count = 1


def tag(now, tag_name, nickname="", color="black"):
    len1 = len(now) + 2
    len2 = len(nickname) + 1
    text.tag_add(tag_name + "0", "{}.0".format(count), "{}.1".format(count))
    text.tag_configure(tag_name + "0", foreground="green")
    text.tag_add(tag_name + "1", "{}.1".format(count), "{}.{}".format(count, len1))
    text.tag_configure(tag_name + "1", foreground="purple")
    text.tag_add(tag_name + "2", "{}.{}".format(count, len1), "{}.{}".format(count, len1 + 2))
    text.tag_configure(tag_name + "2", foreground="green")
    text.tag_add(tag_name + "3", "{}.{}".format(count, len1 + 2), "{}.{}".format(count, len1 + len2 + 2))
    text.tag_configure(tag_name + "3", foreground=color)


button_frame = tk.Frame(master=root)
button_frame.pack()


def buttons():
    for i in "Connect", "Clear", "Exit":
        b = tk.Button(master=button_frame, text=i)
        b.pack(side="left")
        yield b


b1, b2, b3 = buttons()


class Server(socket.socket):
    ip = ""
    host = 12345
    clients = []
    client_names = []

    def __init__(self):
        socket.socket.__init__(self, socket.AF_INET, socket.SOCK_STREAM)
        self.bind((self.ip, self.host))

    def __connect__(self):
        global count
        self.listen(10)
        now = str(datetime.now())[:-7]
        text.configure(state="normal")
        text.insert("insert", "| {} | Connected.\n".format(now))
        text.configure(state="disabled")
        tag(now=now, tag_name="a")
        count += 1

        def warning():
            global count
            text.configure(state="normal")
            text.insert("insert", "| {} | You are already connected.\n".format(now))
            text.configure(state="disabled")
            tag(now=now, tag_name="b")
            count += 1

        b1.configure(command=warning)
        self.thread_control()

    def __accept__(self):
        global count
        c, addr = self.accept()
        data = c.recv(1024).decode("utf-8")
        self.client_names.append(data)
        now = str(datetime.now())[:-7]
        self.clients.append((c, data))
        text.configure(state="normal")
        text.insert("insert", "| {} | {} connected.\n".format(now, data))
        text.configure(state="disabled")
        tag(now=now, tag_name="c", nickname=data, color="black")
        count += 1
        client_frame = tk.Frame(master=right_frame)
        client_frame.pack()
        client_label = tk.Label(master=client_frame, text=data, width=20, bd=1, relief="sunken")
        client_label.pack(side="left")
        entry = tk.Entry(master=client_frame, width=50)
        entry.pack(side="left")
        send_button = tk.Button(master=client_frame, text="Send")
        send_button.pack(side="left")

        def send():
            global count
            respond = "Server: {}".format(str(entry.get()))
            __now__ = str(datetime.now())[:-7]
            entry.delete("0", "end")
            try:
                c.sendall(bytes(respond.encode("utf-8")))
                text.configure(state="normal")
                text.insert("insert", "| {} | {}\n".format(__now__, respond))
                text.configure(state="disabled")
                tag(now=__now__, tag_name="d", nickname="Server", color="blue")
                count += 1
            except BrokenPipeError:
                text.configure(state="normal")
                text.insert("insert", "| {} | {} has been disconnected.\n".format(now, data))
                text.configure(state="disabled")
                tag(now=now, tag_name="e", nickname=data, color="red")
                count += 1
                client_frame.destroy()

        def thread_send():
            __thread_send__ = threading.Thread(target=send)
            __thread_send__.start()

        send_button.configure(command=thread_send)

    def __receive__(self):
        for i, j in enumerate(self.clients):

            def receive():
                global count
                data = j[0].recv(1024).decode("utf-8")
                now = str(datetime.now())[:-7]
                if len(data) == 0:
                    pass
                else:
                    text.configure(state="normal")
                    text.insert("insert", "| {} | {}\n".format(str(datetime.now())[:-7], data))
                    text.configure(state="disabled")
                    tag(now=now, tag_name="f", nickname=self.client_names[i], color="red")
                    count += 1

            __thread_receive__ = threading.Thread(target=receive)
            __thread_receive__.start()

    def thread_control(self):
        while True:
            thread_accept = threading.Thread(target=self.__accept__)
            thread_accept.daemon = True
            thread_accept.start()
            thread_accept.join(1)
            thread_receive = threading.Thread(target=self.__receive__)
            thread_receive.daemon = True
            thread_receive.start()
            thread_receive.join(1)


server = Server()


def connect():
    thread_connect = threading.Thread(target=server.__connect__)
    thread_connect.start()


def clear():
    text.configure(state="normal")
    text.delete("1.0", "end")
    text.configure(state="disabled")


def destroy():
    import os
    import signal
    os.kill(os.getpid(), signal.SIGKILL)


b1.configure(command=connect)
b2.configure(command=clear)
b3.configure(command=destroy)

main_thread = threading.Thread(target=root.mainloop)
main_thread.run()

client.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from datetime import datetime
import socket
import threading
try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk

root = tk.Tk()
root.title("Client")
text = tk.Text(master=root, state="disabled")
text.pack(expand=True, fill="both")
count = 1


def tag(now, tag_name, nickname="", color="black"):
    len1 = len(now) + 2
    len2 = len(nickname) + 1
    text.tag_add(tag_name + "0", "{}.0".format(count), "{}.1".format(count))
    text.tag_configure(tag_name + "0", foreground="green")
    text.tag_add(tag_name + "1", "{}.1".format(count), "{}.{}".format(count, len1))
    text.tag_configure(tag_name + "1", foreground="purple")
    text.tag_add(tag_name + "2", "{}.{}".format(count, len1), "{}.{}".format(count, len1 + 2))
    text.tag_configure(tag_name + "2", foreground="green")
    text.tag_add(tag_name + "3", "{}.{}".format(count, len1 + 2), "{}.{}".format(count, len1 + len2 + 2))
    text.tag_configure(tag_name + "3", foreground=color)


entry = tk.Entry(master=root)
entry.pack(expand=True, fill="x")
frame = tk.Frame(master=root)
frame.pack()


def buttons():
    for i in "Connect", "Create A Nickname", "Send", "Clear", "Exit":
        b = tk.Button(master=frame, text=i)
        b.pack(side="left")
        yield b


b1, b2, b3, b4, b5 = buttons()
__nickname__ = ""


class Client(socket.socket):
    ip = ""
    host = 12345

    def __init__(self):
        socket.socket.__init__(self, socket.AF_INET, socket.SOCK_STREAM)

    def __connect__(self):
        global count
        now = str(datetime.now())[:-7]
        if __nickname__ != "":
            try:
                self.connect((self.ip, self.host))
                text.configure(state="normal")
                text.insert("insert", "| {} | Connected.\n".format(now))
                text.configure(state="disabled")
                tag(now=now, tag_name="a")
                count += 1
                self.sendall(bytes("{}".format(__nickname__).encode("utf-8")))

                def warning():
                    global count
                    text.configure(state="normal")
                    text.insert("insert", "| {} | You are already connected.\n".format(now))
                    text.configure(state="disabled")
                    tag(now=now, tag_name="b")
                    count += 1

                b1.configure(command=warning)
                self.receive()
            except ConnectionRefusedError:
                text.configure(state="normal")
                text.insert("insert", "| {} | The server is not online.\n".format(now))
                text.configure(state="disabled")
                tag(now=now, tag_name="c")
                count += 1
        else:
            text.configure(state="normal")
            text.insert("insert", "| {} | You must create a nickname.\n".format(now))
            text.configure(state="disabled")
            tag(now=now, tag_name="d")
            count += 1

    def receive(self):
        global count
        while True:
            data = self.recv(1024).decode("utf-8")
            now = str(datetime.now())[:-7]
            if len(data) == 0:
                pass
            else:
                text.configure(state="normal")
                text.insert("insert", "| {} | {}\n".format(now, data))
                text.configure(state="disabled")
                tag(now=now, tag_name="e", nickname="Server", color="red")
                count += 1

    def do_nothing(self):
        pass

    def create_nickname(self):
        b2.configure(command=self.do_nothing)
        __frame__ = tk.Frame(master=root)
        __frame__.pack()
        __entry__ = tk.Entry(master=__frame__)
        __entry__.grid(row=0, column=0)
        __button__ = tk.Button(master=__frame__, text="Accept Your Nickname")
        __button__.grid(row=1, column=0)

        def __create_nickname__():
            global __nickname__, count
            now = str(datetime.now())[:-7]
            if __entry__.get() == "":
                text.configure(state="normal")
                text.insert("insert", "| {} | You must write a nickname.\n".format(now))
                text.configure(state="disabled")
                tag(now=now, tag_name="f")
                count += 1
            else:
                __nickname__ = __entry__.get()
                __frame__.destroy()
                text.configure(state="normal")
                text.insert("insert", "| {} | Nickname has changed to: '{}'.\n".format(now, __nickname__))
                text.configure(state="disabled")
                tag(now=now, tag_name="g")
                count += 1
                root.title(__nickname__)
                b2.destroy()

        __button__.configure(command=__create_nickname__)

    def __send__(self):
        global count
        respond = "{}: {}".format(__nickname__, str(entry.get()))
        now = str(datetime.now())[:-7]
        entry.delete("0", "end")
        try:
            self.sendall(bytes(respond.encode("utf-8")))
            text.configure(state="normal")
            text.insert("insert", "| {} | {}\n".format(now, respond))
            text.configure(state="disabled")
            tag(now=now, tag_name="h", nickname=__nickname__, color="blue")
            count += 1
        except BrokenPipeError:
            text.configure(state="normal")
            text.insert("insert", "| {} | Server has been disconnected.\n".format(now))
            text.configure(state="disabled")
            tag(now=now, tag_name="i")
            count += 1
            self.close()


client = Client()


def connect():
    thread_connect = threading.Thread(target=client.__connect__)
    thread_connect.start()


def send():
    thread_send = threading.Thread(target=client.__send__)
    thread_send.start()


def clear():
    text.configure(state="normal")
    text.delete("1.0", "end")
    text.configure(state="disabled")


def destroy():
    import os
    import signal
    os.kill(os.getpid(), signal.SIGKILL)


b1.configure(command=connect)
b2.configure(command=client.create_nickname)
b3.configure(command=send)
b4.configure(command=clear)
b5.configure(command=destroy)

main_thread = threading.Thread(target=root.mainloop)
main_thread.run()
1 Beğeni

Tekrar merhaba, programa yeni özellikler ekledim.

Eklenen özellikler:

  1. Ekrana bastırılan yazıların bazıları renklendirildi.
  2. Dosya gönderme işlevi eklendi.

Ekran görüntüleri:

  1. Önce server.py dosyasını çalıştırıyoruz.
  2. Şimdi sunucuyu internete bağlayalım.
  3. Şimdi istemci programı çalıştıralım.
    Ekran%20G%C3%B6r%C3%BCnt%C3%BCs%C3%BC%20-%202018-04-29%2017-52-22
  4. İstemci bir kullanıcı adı seçmeden sunucuya bağlanamaz.
    Ekran%20G%C3%B6r%C3%BCnt%C3%BCs%C3%BC%20-%202018-04-29%2017-52-53
  5. Kullanıcı adı boş bırakılamaz.
    Ekran%20G%C3%B6r%C3%BCnt%C3%BCs%C3%BC%20-%202018-04-29%2017-53-39
  6. Kullanıcı adını belirledikten sonra sunucuya bağlanalım.
    Ekran%20G%C3%B6r%C3%BCnt%C3%BCs%C3%BC%20-%202018-04-29%2017-54-51
  7. Sunucu ekranına bir göz atalım.
  8. Başka bir istemciyi daha sunucuya bağlayalım.
    Ekran%20G%C3%B6r%C3%BCnt%C3%BCs%C3%BC%20-%202018-04-29%2017-56-07
  9. Sunucu ekranına tekrar bakalım.
  10. Önce Ali’ye mesaj gönderelim.
  11. Şimdi de Ahmet’e mesaj gönderelim.
  12. Şimdi Ali sunucuya bir mesaj yazsın.
  13. Şimdi de Ahmet sunucuya bir mesaj yazsın.
  14. Şimdi dosya gönderme düğmesine tıklayalım.

    Dosya gönderme düğmesine tıkladıktan sonra sunucuya bağlanmış kullanıcı sayısı kadar düğme
    oluşturulur, bu düğmelerden birine tıklayarak kime dosya göndermek istediğimizi belirliyoruz. İlk olarak Ali’ye dosya gönderelim.
  15. Karşımıza bir tane dosya açma paneli geldi. Buradan göndermek istediğimiz dosyayı seçelim.
  16. Şimdi de Ali’nin ekranına bakalım.

    Dosyamız başına new_ eki alarak bilgisayara kaydedildi.
  17. Şimdi de Ahmet’e bu new_xpython.ico dosyasını gönderelim.

    Ahmet’e gelen dosyanın ismi new_new_python.ico şeklinde kaydedildi.
  18. Ahmet de bu gelen dosyayı sunucuya göndersin.
  19. Sunucunun ekranına bir bakalım.

NOT: Dosya gönderme işlemi şuanlık boyutu çok fazla olmayan dosyalar için geçerlidir (Sınırı 2147483648’e (=2 ** 31’e) kadar olan tampon değeri). Belki ilerleyen zamanlarda daha büyük dosyalar için de geçerli olabilir.

Kodlar:
https://github.com/dildeolupbiten/A-gui-chat-program/blob/master/tkserver.py
https://github.com/dildeolupbiten/A-gui-chat-program/blob/master/tkclient.py

Programla alakalı bir bug tespit eden veya önerisi olan arkadaşlar görüşlerini bildirirlerse sevinirim.

2 Beğeni