web-dev-qa-db-ja.com

TCP Pythonチャットサーバーに複数のクライアントを配置するにはどうすればよいですか?

これを複数のクライアントに受け入れさせる方法と、現時点で受け入れられない理由についてのヘルプはありますか?ありがとう!

また、このコードで何か間違っていることはありますか? Python 3.4のチュートリアルが見つからないため、ほとんどPython 2つのチュートリアルに従っています。

これが私のサーバーコードです:

import socket
import time
import os
from threading import Thread

folderPath = "Chat Logs"
filePath = folderPath + "/" + str(time.strftime("%H-%M-%S_%d-%m-%Y")) + ".txt"

def clientHandler(c):          
    while True:
        data = c.recv(1024)
        if not data:
            break

    data = data.decode("UTF-8")

    message = str(data[:data.index("§")])
    nick = str(data[data.index("§")+1:])

        print(nick + ": " + message)
        saveChat(nick, message)
        print("   Sending: " + data)
        c.send(bytes(data, "UTF-8"))

    c.close()

def saveChat(nick, message):
    if not os.path.exists(folderPath):
        os.makedirs(folderPath)
    if not os.path.exists(filePath):
        f = open(filePath, "a")
        f.close()

    f = open(filePath, "a")
    f.write(nick + ": " + message + "\n")
    f.close()

def Main():
    Host = str(socket.gethostbyname(socket.gethostname()))
    port = 5000

    print(Host + ":" + str(port) + "\n")
    Clients = int(input("Clients: "))

    s = socket.socket()
    s.bind((Host, port))
    s.listen(Clients)
    for i in range(Clients):
        c, addr = s.accept()
        print("Connection from: " + str(addr))

        Thread(target=clientHandler(c)).start()
    s.close()

if __name__ == "__main__":
    Main()

そして、これが私のクライアントコードです:

import socket

def Main():
    print("Send 'q' to exit\n")
    address = str(input("ip:port -> "))
    nick = input("nick: ")

    try:
        if address.index(":") != 0:
            Host = address[:address.index(":")]
            port = int(address[address.index(":")+1:])
    except ValueError:
        Host = address
        port = 5000

    s = socket.socket()
    s.connect((Host, port))

    message = input("-> ")

    while message != "q":
        s.send(bytes(message + "ยง" + nick, "UTF-8"))
        data = s.recv(1024)
        data = data.decode("UTF-8")
        data2 = data

        messageServer = str(data[:data.index("ยง")])
        nickServer = str(data[data.index("ยง")+1:])
        if not data == data2:
            print(nickServer + ": " + messageServer)
        message = input("-> ")
    s.close()

if __name__ == "__main__":
    Main()
7
artman41

まず第一に、私はこれらのチュートリアルが非常に役立つことに気づきました: BinaryTides

これは、複数のクライアントを受け入れる単純なtcpサーバーの例です。これはすべて、クライアントからデータを受信し、「OK ..」+ the_dataを返します。ただし、接続されているすべてのクライアントにデータ(チャットメッセージ)をブロードキャストする機能を持つように簡単に変更できます。この例では、スレッドを使用しています。 selectモジュールをグーグルで検索する必要があります。スレッドに関して、a)ジョブに適切なモジュール/メソッドを使用しており、b)適切な方法で呼び出していることを確認しますか?

import socket
import sys
from thread import start_new_thread

Host = '' # all availabe interfaces
PORT = 9999 # arbitrary non privileged port 

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
    print("Could not create socket. Error Code: ", str(msg[0]), "Error: ", msg[1])
    sys.exit(0)

print("[-] Socket Created")

# bind socket
try:
    s.bind((Host, PORT))
    print("[-] Socket Bound to port " + str(PORT))
except socket.error, msg:
    print("Bind Failed. Error Code: {} Error: {}".format(str(msg[0]), msg[1]))
    sys.exit()

s.listen(10)
print("Listening...")

# The code below is what you're looking for ############

def client_thread(conn):
    conn.send("Welcome to the Server. Type messages and press enter to send.\n")

    while True:
        data = conn.recv(1024)
        if not data:
            break
        reply = "OK . . " + data
        conn.sendall(reply)
    conn.close()

while True:
    # blocking call, waits to accept a connection
    conn, addr = s.accept()
    print("[-] Connected to " + addr[0] + ":" + str(addr[1]))

    start_new_thread(client_thread, (conn,))

s.close()
11
Totem

チェックアウト: http://etutorials.org/Programming/Python+tutorial/Part+IV+Network+and+Web+Programming/Chapter+19.+Sockets+and+Server-Side+Network+Protocol+ Modules/19.3 + Event-Driven + Socket + Programs / 。例19-6は、チャットアプリケーションのHello Worldのようなものです(selectシステムコールを使用したもの)。より低レベルの(C)インサイトシステムネットワーキングの基本については、 http://beej.us/guide/bgnet/output/html/multipage/index.html も参照してください。

3
PSkocik