質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.90%

pythonでクライアントサーバーシステムを作ってるのですが、GUIで表示されない部分があります。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 252

asdfghjklz

score 1

前提・実現したいこと

クライアントサーバーシステムを構築していて、複数のクライアントの接続ができるようにしてます。あるクライアントがメッセージを送信すると他のクライアントにも送信されたメッセージが表示されるようにしたいです。GUIを使ってやっています。

しかし、発言を押しても表示されません。どこが間違っているか教えてほしいです。

該当のソースコード

サーバー側
# -*- coding: utf-8 -*-

import socket
import select

def send_to(sock,msg):
    try:
        sock.send(msg.encode())
        return True
    except:
        sock.close()
        return False

def broadcast(socklist,msg):
    for sock in socklist:
        if not send_to(sock,msg):
            sock_list.remove(sock)

host='127.0.0.1'
port=50000
backlog=10
bufsize=4096

server_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print("socket is created")

try:
    server_sock.bind((host,port))
    print("socket bind")
    server_sock.listen(backlog)
    print("socket listen")
    sock_list=[server_sock]
    client_sock_table={}
    while True:
        r_ready_sockets,w_ready_sockets,e_ready_sockets=select.select(sock_list,[],[])
        for sock in r_ready_sockets:
            if sock==server_sock:
                conn,address=sock.accept()
                sock_list.append(conn)
                client_sock_table[address[1]]=conn
                sock_list.remove(server_sock)
                broadcast(sock_list,"ポート" + str(address[1]) + "番のユーザーが接続しました")
                sock_list.append(server_sock)
                print(str(address)+"is connected")
            else:
                try:
                    b_msg=sock.recv(bufsize)
                    msg=b_msg.decode('utf-8')
                    if len(msg)==0:
                        sock.close()
                        sock_list.remove(sock)
                    else:
                        sender_port=None
                        for key,val in client_sock_table.items():
                            if val==sock:
                                sender_port=key
                                break
                            if sender_port is not None:
                                sock_list.remove(server_sock)
                                broadcast(sock_list,str(sender_port)+":" + msg)
                                sock_list.append(server_sock)
                except:
                    sock.close()
                    sock_list.remove(sock)
                    sock_list.remove(server_sock)
                    broadcast(sock_list,"someone disconnected")
                    sock_list.append(server_sock)
except Exception as e:
    print("Exception!")
    print(e)
    server_sock.close()



クライアント側
# -*- coding: utf-8 -*-

import tkinter as tk
import socket, select
import threading

def send_msg(ev=None):
    if len(entered_txt.get())<=0:
        return
    sock.send(entered_txt.get().encode())
    etr.delete(0,tk.END)

def receive_msg(msg):
    if text_w is None:
        return
    text_w.configure(state=tk.NORMAL)
    text_w.insert(tk.END,msg+"\n")
    text_w.configure(state=tk.DISABLED)
    text_w.see(tk.END)

#サーバーから送られてきたメッセージをストックする
def stock_msg(msg):
    stocked_msg.append(msg)

#ストックされたメッセージに対してreceive_msgを呼び出す
def check_msg():
    while len(stocked_msg)>0:
        receive_msg(stocked_msg.pop(0))
    #after(time.func)
    #funcの実行(呼び出し)をtime[ミリ秒]ごとに行う
    text_w.after(200,check_msg)

root=tk.Tk(None)
root.title("サンプルチャット")

frame=tk.Frame(master=root,width=480,height=320)

label1=tk.Label(master=frame,text="サンプルチャット",font=('メイリオ','12'),bg="#cccccc")
label1.place(relx=0,rely=0,relwidth=1.0,relheight=0.1)

#複数行テキスト
text_w=tk.Text(master=frame,state=tk.DISABLED,font=('メイリオ','10'),bg="white")
text_w.place(relx=0.05,rely=0.1,relwidth=0.85,relheight=0.7)

#スクロールバー
sb_y=tk.Scrollbar(master=frame,orient=tk.VERTICAL,command=text_w.yview)
sb_y.place(relx=0.90,rely=0.1,relwidth=0.05,relheight=0.7)
text_w.config(yscrollcommand=sb_y.set)

entered_txt=tk.StringVar()
#1行編集テキスト
etr=tk.Entry(master=frame,width=30,textvariable=entered_txt)
etr.bind('<Return>',send_msg)
etr.place(relx=0.05,rely=0.85,relwidth=0.65,relheight=0.1)

#ボタン
bt=tk.Button(master=frame,text='発言',bg='skyblue',command=send_msg)
bt.place(relx=0.75,rely=0.85,relwidth=0.35,relheight=0.1)

frame.pack()

host='127.0.0.1'
port=50000
bufsize=4096

sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

#送られてきたメッセージをストックするためのリスト
stocked_msg=[]

def listen():
    try:
        sock.connect((host,port))
        while True:
            r_ready_sockets,w_ready_sockets,e_ready_sockets=select.select([sock],[],[])
            try:
                recev_msg=sock.recv(bufsize).decode()
            except:
                break
            stock_msg(recev_msg)
    except Exception as e:
        print(e)
    finally:
        sock.close()
        receive_msg('サーバとの接続が切断されました')
check_msg()

thrd=threading.Thread(target=listen)
thrd.start()

root.mainloop()

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

server側のbreakとその次の行を削除すれば良いです。

break
if sender_port is not None:


forループから抜けてしまって永遠にbroadcastされないです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/02 22:42

    そこのインデントを左にずらしたらできました。ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.90%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Pythonに関する質問
  • pythonでクライアントサーバーシステムを作ってるのですが、GUIで表示されない部分があります。