Python Socket Ve Threading Kaynak Bilen Var mı?

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

Artık büyük boyutlu dosyalar da gönderilebilir. Kodlar güncellenmiştir.

Merhabalar,

Öncelikle, son derece yakışıklı duruyor yazdığınız örnek fakat bir server’in yazdığınız gibi çalışmaması gerektiğini düşünüyorum.

Server sadece clientler arasındaki iletişimi düzenliyor olmalı. Aşağıda yazdığım basit server örneğini incelerseniz, ne demek istediğimi daha iyi anlarsınız. (Bir client yazmaya gerek duymadım, mantık anlaşılıyor diye düşünüyorum.)

Link: http://dpaste.com/2ZJ2FMY.txt

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

__author__ = '@r0ark'

import os, sys, struct
import socket, threading, base64

def log(msg):
    sys.stdout.write('[%s] - %s\n' % (time.ctime(), msg))
    sys.stdout.flush()

def send(conn, data):
    if type(data) != bytes:
        data = bytes(data, 'utf-8')

    data = struct.pack('>I', len(data)) + data
    conn.sendall(data)

def _recv(conn, buff):
    data = b''

    while len(data) < buff:
        packet = conn.recv(buff - len(data))

        if not packet:
            break

        data += packet

    return data

def recv(conn):
    data_len = _recv(conn, 4)

    if not data_len:
        return None

    data_len = struct.unpack('>I', data_len)[0]
    return _recv(conn, data_len)

class Connection:
    def __init__(self, conn, addr):
        self.conn
        self.addr

class Server:
    clients = []
    
    def __init__(self, host='0.0.0.0', port=8000):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        self.socket.bind((host, port))
        self.socket.listen(10)

    def send_all(self, message):
        for client in self.clients:
            try:
                send(client.conn, message)
            except Exception as err:
                log('Error: ' + err.message)

    def handle_client(self, connection):
        while True:
            message = recv(connection.conn)

            if message:
                message = ': '.join(connection.addr[0], message)
                self.send_all(message)

    def serve(self):
        while True:
            conn, addr = self.socket.accept()
            log('New connection -> ' + addr[0])
            
            connection = Connection(conn, addr)
            self.clients.append(connection)

            threading.Thread(self.handle_client, args=(connection, )).start()

if __name__ = '__main__':
    server = Server()
    server.serve()

Şu an group chat gibi bir şey ama tabii ki odalar, private kısımlar vs bir çok özellik eklenebilir. Bu arada, bağlanan client için Connection adında bir sınıf tanımlamak işi daha da kolaylaştırabilir. Özellikle açık anahtarlı şifreleme kullanacak olursak.

Merhaba, katılımınız için teşekkür ederim. Dediğiniz gibi bir sunucunun işlevi istemciler arasındaki iletişimi düzenliyor olmalı. Yalnız şu ana kadar sunucuyu bahsettiğiniz gibi ayarlamak için fırsat olmadı. Açıkçası şu an nasıl yapacağımı da bilmiyorum. Biraz araştırmam lazım.

Edit: Az önce bahsettiğiniz konuyla alakalı bir örnek yapıyordum. Sunucu herhangi bir istemciden gelen mesajları, gelir gelmez diğer istemcilere gönderdi. Neyse uygulamayı biraz geliştirmeye çalışayım. Kodlar aşağıdadır:

server.py

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

import socket
import threading

DATA = ""


class Server(socket.socket):
    clients = []

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

    def __connect__(self):
        self.bind(("", 12346))
        self.listen(10)

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

    def __receive__(self):
        global DATA
        if self.conn is not None:
            data = str(self.conn.recv(1024))[1:]
            DATA = data
            if len(data) == 2:
                pass
            else:
                print("\n{}".format(data[1:-1]), flush=True)

    def __send__(self):
        global DATA
        for i in self.clients:
            try:
                i.send(bytes(DATA.encode("utf-8")))
            except BrokenPipeError:
                print("\nClient has been disconnected\n")
                self.clients.remove(i)
        DATA = ""


server = Server()
thread_connect = threading.Thread(target=server.__connect__)
thread_connect.start()
while True:
    thread_accept = threading.Thread(target=server.__accept__)
    thread_accept.daemon = True
    thread_accept.start()
    thread_accept.join(1)
    thread_receive = threading.Thread(target=server.__receive__)
    thread_receive.daemon = True
    thread_receive.start()
    thread_receive.join(1)
    thread_send = threading.Thread(target=server.__send__)
    thread_send.daemon = True
    thread_send.start()
    thread_send.join(1)

client.py

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

import socket
import threading

nickname = input("Nickname: ")


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

    def __connect__(self):
        self.connect(("", 12346))

    def __receive__(self):
        try:
            data = str(self.recv(1024))[1:]
            if len(data) == 2:
                pass
            else:
                print(data[2:-2])
        except OSError:
            pass

    def __send__(self):
        respond = input()
        self.sendall(bytes("<{}>: {}".format(nickname, respond).encode("utf-8")))


client = Client()
thread_connect = threading.Thread(target=client.__connect__)
thread_connect.start()
while True:
    thread_receive = threading.Thread(target=client.__receive__)
    thread_receive.start()
    thread_send = threading.Thread(target=client.__send__)
    thread_send.daemon = True
    thread_send.start()
    thread_send.join(1)

Vaktim olmadığı için bir client yazamadım ama bahsettiğim olay, şu projede uygulanmış.

1 Beğeni

Bu çalışmaya da bakacağım. Teşekkür ederim.

Uygulamayı indirip çalıştırdım, mantığını anlamak için programı biraz kurcalıyordum da:
Mesela:

<join> oda_ismi

yazarak bir odaya girdim.

Daha sonra başka bir istemciyi sunucuya bağladım.

<list>

yazdığımda açık olan odalar ekrana yazdırıldı…
Ama önce başka bir oda daha oluşturayım dedim.

<join> yeni_oda

yazdım. Ve bu odadayken de

<join> oda_ismi

yazarak odadan odaya geçiş yaptım.
Kullanıcıların mesajlaşabilmesi için bir odaya girmesi gerekiyor. Bazı komutlar yardımıyla odalar oluşturmayı veya odalardan çıkmayı ve ancak bu sayede istemciler arasında iletişim kurulmasını sağlayan bir program oluşturmayı deneyeceğim. Sizinle yukarıda paylaştığım son program ise, herhangi bir odaya girmeden, istemcilerin birbirleriyle mesajlaşmasını sağlıyor.
Tekrar teşekkür ederim.

Hocam İyi Güzel Yapmışsınız Hepinizin Ellerine Sağlıkta Bu Örnekler Beni Aşar :smiley: Anlaması 10 Yılımı Alır Zaten :smiley:

Her gün bir kaç saatinizi ayırabilirseniz, daha kısa sürelerde beni aşar dediğiniz örnekleri rahat anlayabilirsiniz. Sadece biraz ilgi istiyor. :slight_smile:

Hocam İyi Güzelde Thread Ve Socket Falan Hakkında Hiç Bilgim Yok Kaynak Bulamadım Okuyamadım O Yüzden Aşar :slight_smile: Fakat Kaynak Bulabilirsem Tabiiki İncelerim.

Kaynak mı bulamadınız? Nasıl bulamadınız anlamıyorum. Google’a “threading python türkçe” yazdığınızda karşınıza inceleyebileceğiniz en az 5, 6 sayfa çıkar zaten. Aynı şekilde socket’i de aratsanız yine kaynak bulursunuz. Üstelik bu forumda hatta bu başlıkta en basitinden socket örnekleri mevcut daha da basiti yoktur bence. Yani yapmanız gereken okuduğunuz kodları incelemek, “o ne işe yarıyormuş acaba” diye merak edip sağını solunu değiştirmek ve sonuçları gözlemlemek.

1 Beğeni

@r0ark
Dediğiniz gibi sunucuyu sadece istemciler arasındaki mesajlaşmayı ayarlayacak şekilde bir program yazdım. İstemciler mesajlaşabilmek için chat odalarına girmek zorundalar, yoksa mesajlaşamıyorlar. Paylaştığınız örnek programda kullanıcı komutları girmek için <komut> yazıyordu, bu çalışmada /komut şeklinde değiştirildi. Ama işlev olarak diğer programa benziyor diyebilirim. Program henüz yeni bitti sayılır bu yüzden hatalar olabilir, tespit ettiğiniz hataları paylaşırsanız sevinirim.

Kodlar:

server.py

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

import re
import socket
import threading

DATA = ""
NICKNAME = ""
ROOMS = []
NICKNAMES = []
ROOMS_NICKNAMES = []


class Server(socket.socket):
    clients = []

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

    def __connect__(self):
        self.bind(("", 12346))
        self.listen(10)
        print("Waiting for clients...")

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

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

            def receive():
                global DATA, NICKNAME
                data = str(i.recv(1024))[1:]
                DATA = data
                if len(data) == 2:
                    pass
                else:
                    if ":nickname:" in DATA:
                        nickname = DATA[len(" :nickname: "):-1]
                        if nickname not in NICKNAMES:
                            NICKNAMES.append(nickname)
                        else:
                            NICKNAMES.append(nickname)
                            message = "This nickname is used."
                            self.clients[NICKNAMES.index(nickname, 1)].send(bytes(message.encode("utf-8")))
                            NICKNAMES.remove(NICKNAMES[NICKNAMES.index(nickname, 1)])
                        DATA = ""
                    elif ":room:" in DATA:
                        room, NICKNAME = DATA[8:-1].split(" ")
                        ROOMS_NICKNAMES.append(room)
                        ROOMS_NICKNAMES.append(NICKNAME)
                        if room not in ROOMS:
                            ROOMS.append(room)
                        DATA = ""
                        NICKNAME = ""
                    elif ":list:" in DATA:
                        self.clients[NICKNAMES.index(DATA[len(" :list: "):-1])].send(
                            bytes("Room: {}".format(", ".join(ROOMS)).encode("utf-8")))
                        DATA = ""

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

    def __send__(self):
        global DATA, NICKNAME
        if ".:!:." in DATA:
            regex = "".join(re.findall("\.:!:\..+\.:!:\.", DATA))
            NICKNAME = regex.replace(".:!:.", "")
            DATA = DATA.replace(regex, "")
            try:
                chat_groups = []
                for x, y in enumerate(ROOMS):
                    group = []
                    for i, j in enumerate(ROOMS_NICKNAMES):
                        if j == ROOMS[x]:
                            group.append(ROOMS_NICKNAMES[i + 1])
                    if group not in chat_groups:
                        chat_groups.append(group)
                for i in chat_groups:
                    if NICKNAME in i:
                        for j in i:
                            self.clients[NICKNAMES.index(j)].send(bytes(DATA.encode("utf-8")))
            except ValueError:
                pass
        DATA = ""


server = Server()
thread_connect = threading.Thread(target=server.__connect__)
thread_connect.start()
while True:
    thread_accept = threading.Thread(target=server.__accept__)
    thread_accept.daemon = True
    thread_accept.start()
    thread_accept.join(1)
    thread_receive = threading.Thread(target=server.__receive__)
    thread_receive.start()
    thread_send = threading.Thread(target=server.__send__)
    thread_send.daemon = True
    thread_send.start()
    thread_send.join(1)

client.py

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

import time
from datetime import datetime
import socket
import threading

DATA = ""
NICKNAME = ""
ROOM = ""


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

    def __connect__(self):
        self.connect(("", 12346))
        print("| {} | Welcome to the chat program.\n".format(str(datetime.now())[:-7]))
        print("Commands:\n\t/nick <new_nickname>\n\t/join <room_name>\n\t/list\n\t/quit\n".expandtabs(4))

    def __receive__(self):
        global DATA
        try:
            data = str(self.recv(1024))[1:]
            if len(data) == 2:
                pass
            else:
                if "Room:" in data:
                    for i in data[6:-1].split(","):
                        print("\t{}".expandtabs(4).format(i[1:]))
                elif "This nickname is used." in data:
                    print("| {} | {}".format(str(datetime.now())[:-7], data[1:-1]))
                    DATA = data[1:-1]
                else:
                    print(data[2:-2])
        except OSError:
            pass

    def __send__(self):
        global NICKNAME, ROOM, DATA
        respond = input()
        if "/nick" in respond:
            if respond == "/nick":
                print("| {} | You must create a nickname.".format(str(datetime.now())[:-7]))
            else:
                NICKNAME = respond[6:]
                if " " in NICKNAME or NICKNAME == "":
                    print("| {} | Do not use space in your nickname.".format(str(datetime.now())[:-7]))
                else:
                    self.sendall(bytes(":nickname: {}".format(NICKNAME).encode("utf-8")))
                    time.sleep(0.1)
                    if "This nickname is used." not in DATA:
                        print("| {} | Your nickname has changed to {}.".format(str(datetime.now())[:-7], NICKNAME))
                    else:
                        NICKNAME = ""
            DATA = ""
        elif "/join" in respond:
            if respond == "/join":
                print("| {} | You must write a room.".format(str(datetime.now())[:-7]))
            else:
                ROOM = respond[6:]
                if " " in ROOM or ROOM == "":
                    print("| {} | Do not use space in room name.".format(str(datetime.now())[:-7]))
                else:
                    if NICKNAME != "":
                        self.sendall(bytes(":room: {} {}".format(ROOM, NICKNAME).encode("utf-8")))
                        print("| {} | Joined {}.".format(str(datetime.now())[:-7], ROOM))
                    else:
                        print("| {} | You must create a nickname.".format(str(datetime.now())[:-7]))
        elif "/list" in respond:
            if NICKNAME != "":
                self.sendall(bytes(":list: {}".format(NICKNAME).encode("utf-8")))
                print("| {} | Available Rooms:".format(str(datetime.now())[:-7]))
            else:
                print("| {} | You must create a nickname.".format(str(datetime.now())[:-7]))
        elif "/quit" in respond:
            import os
            import signal
            os.kill(os.getpid(), signal.SIGKILL)
        else:
            if NICKNAME != "":
                if ROOM != "":
                    self.sendall(bytes(".:!:.{}.:!:.{}: {}".format(NICKNAME, NICKNAME, respond).encode("utf-8")))
                else:
                    print("| {} | Join a room.".format(str(datetime.now())[:-7]))
            else:
                print("| {} | Create a nickname.".format(str(datetime.now())[:-7]))


client = Client()
thread_connect = threading.Thread(target=client.__connect__)
thread_connect.start()
while True:
    thread_receive = threading.Thread(target=client.__receive__)
    thread_receive.start()
    thread_send = threading.Thread(target=client.__send__)
    thread_send.daemon = True
    thread_send.start()
    thread_send.join(1)

bir şey soracaktım bu ne işe yarıyor :smiley:
ve client ile serveri nasıl bağlayabilirim ikisinide ayrı ayrı açtıktan sonra nasıl birbirine bağlayacam?

Bu, istemcilerin birbirleriyle mesajlaşmasına yarıyor.
Client ve serveri şöyle bağlayabilirsiniz:

  1. Önce server.py’yi çalıştırırsınız.
  2. Sonra başka bir oturumda client.py’yi çalıştırırsınız.
  3. client.py’yi çalıştırdıktan sonra ekranda gözüken yönergelere bakarsınız. Orada komutlar “Commands:” adı altında listelenmiştir. Bu listelenmiş komutlardan olan /nick komutuyla bir nick belirtirsiniz:
/nick tekbir
  1. sonra ya bir odaya girersiniz.
/join herhangi_bir_oda
  1. ya da mevcut bir oda var mı ona bakarsınız:
/list
  1. Sonra başka bir oturumda bir tane daha client.py açıp aynı sunucuya bağlanırsınız.
  2. Bu istemciyle daha önce bağlanan istemcinin mesajlaşmasını istiyorsanız, daha önce bağlanan istemcinin girdiği odaya girersiniz.
# tabi önce nick seçmeniz gerekir.
/nick yeni_nick
# sonra odayı yazarsınız
/join herhangi_bir_oda
  1. Ve artık bu iki istemci birbirleriyle yazışabilirler.

Bu programdaki sunucunun görevi istemciler arasındaki iletişimi düzenlemektir.
Anlattıklarım sizin kendi bilgisayarınızda yapabileceğiniz şeyler. Bu tarz programlarla bir çok kişiyle chat yapılabilir veya karşı tarafa dosyalar gönderebilirsiniz.

1 Beğeni

Hataları tespit için unittest modülünü kullanmaya ne dersiniz?

1 Beğeni