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.
- Ö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.
- Şimdi sunucuyu internete bağlayalım.
Sunucu, istemcilerin kendisine bağlanmasını bekleyedursun.
- Şimdi client.py dosyasını çalıştıralım.
- İstemciye bir kullanıcı adı vermeden, sunucuya bağlanamayız.
- Kullanıcı adını sadece bir kereliğine verebiliriz ve kullanıcı adı boş bırakılamaz.
- 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.
- Şimdi sunucuya bağlanabiliriz.
- İ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.
- “Ahmet” isminde yeni bir istemci daha oluşturalım ve onu da sunucuya bağlayalım.
- Sunucu ekranına bir daha bakalım:
- Şimdi Ali’ye ve Ahmet’e ayrı ayrı mesajlar gönderelim.
- İ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()