ページ 11

tkinterとsocketの同時進行

Posted: 2018年4月02日(月) 16:21
by あかさん
pythonのtkinterとソケットを使いチャットを作ってみようと思うんですが以下のコードで躓いてしまいました。繰り返しチャットができるようにしたいのですがいい案ありますかね?

コード:

from tkinter import *
from tkinter import ttk
import socket

#ソケット
host ="127.0.0.1"
port = 9999
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
server.listen(10)

#ボタンやラベルを載せる枠組み
class ClacApp(ttk.Frame):

    def __init__(self,master=None):
        super().__init__(master)
        self.create_widgets()

    def create_widgets(self):
        static = ttk.Label(text=u'メッセージを送る')
        static.place(x=50, y=80)
        static2 = ttk.Label(text=u'メッセージを受け取る')
        static2.place(x=50,y=140)
        self.EditBox = ttk.Entry(width=40)
        self.EditBox.place(x=50, y=100)
        button = ttk.Button(text=u'送信')
        button.place(x=300, y=98)
        button.bind('<Button-1>', self.push)

    def push(self,event):
        value = self.EditBox.get()
        sock, addr = server.accept()
        sock.sendall(value.encode())

def main():
    root = Tk()
    root.title("メッセージ")
    root.geometry("400x300")
    ClacApp(root)
    root.mainloop()

if __name__ == '__main__':
    main()

Re: tkinterとsocketの同時進行

Posted: 2018年4月03日(火) 06:49
by かずま
サーバーをスレッドで動かせばいいのではないでしょうか。

コード:

# -*- coding: utf-8 -*- 

from tkinter import *
from tkinter import ttk 
import socket
import threading

PORT1 = 9999
PORT2 = 9999

class ServerThread(threading.Thread):
    def __init__(self):
        super(ServerThread, self).__init__()
        self.host = ""
        self.port = PORT1
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.bind((self.host, self.port))
        self.msg = b"" 

    def run(self):
        self.server.listen(10)
        sock, addr = self.server.accept()
        while True:
            recvmsg = sock.recv(1024)
            self.msg += recvmsg + b"\n"
            static = ttk.Label(text = self.msg.decode())
            static.place(x = 50, y = 180)

class ClacApp(ttk.Frame):

    def __init__(self,master=None):
        super().__init__(master)
        self.create_widgets()
        self.no_sock = True

    def create_widgets(self):
        static = ttk.Label(text = u'メッセージを送る')
        static.place(x = 50, y = 80) 
        static2 = ttk.Label(text = u'メッセージを受け取る')
        static2.place(x = 50, y = 140)
        self.EditBox = ttk.Entry(width = 40) 
        self.EditBox.place(x = 50, y = 100)
        button = ttk.Button(text = u'送信')
        button.place(x = 300, y = 98) 
        button.bind('<Button-1>', self.push)

    def push(self, event):
        if self.no_sock:
            host ="127.0.0.1"
            port = PORT2
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.connect((host, port))
            self.no_sock = False
        value = self.EditBox.get()
        self.sock.send(value.encode())

def main():
    th = ServerThread()
    th.setDaemon(True)
    th.start()

    root = Tk()
    root.title("メッセージ")
    root.geometry("400x300")
    app = ClacApp(root)

    root.mainloop()

if __name__ == '__main__':
    main()
サーバーのポート番号を 9999 にして、
クライアントは、そこへコネクトするので、
自分の送信したメッセージを自分のサーバーで受信します。

 PORT1 = 9991
 PORT2 = 9992
としたものと、
 PORT1 = 9992
 PORT2 = 9991
としたものとを用意して、
2つの端末から別々に起動すると、
お互いに相手のメッセージを受信できます。

受信したメッセージの表示方法はいい加減です。