如何在TCP Python聊天服务器上拥有多个客户端?

时间:2014-10-18 22:49:26

标签: python tcp python-multithreading

有关如何让我接受多个客户的任何帮助,以及为什么现在不这样做?谢谢!

另外,这个代码有什么问题吗?我一直在关注Python 2教程,因为我找不到任何Python 3.4

这是我的服务器代码:

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()

2 个答案:

答案 0 :(得分:10)

首先,我发现这些教程非常有用: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()

答案 1 :(得分:3)

结帐: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 (具有select系统调用的那个)就像聊天应用程序的hello世界。您可能还想查看http://beej.us/guide/bgnet/output/html/multipage/index.html以获取更低级别(C)洞察系统网络基础知识。