Python客户端-服务器问题

0 投票
2 回答
1536 浏览
提问于 2025-04-17 16:08

我正在制作一个聊天程序。
我有一个(TCP)服务器,每当收到一个连接请求时,它就会为这个请求创建一个新的线程。

  1. 当客户端退出或终止连接时,我遇到了问题。服务器会报错(如下所示)。我该如何处理这个问题?
  2. 另外,服务器需要把从一个客户端收到的数据发送给另一个(可以更换的)客户端。
    我该怎么实现这个功能呢?

当客户端退出时,我收到这个错误:

Exception in thread Thread-1:
    Traceback (most recent call last):
      File "C:\Python2.7 For Chintoo\lib\threading.py", line 552, in __bootstrap_inner
        self.run()
      File "C:\Python2.7 For Chintoo\lib\threading.py", line 505, in run
        self.__target(*self.__args, **self.__kwargs)
      File "C:\Users\karuna\Desktop\Jython\Python\My Modules\Network\Multi-server.py", line 23, in recv_loop
        data = client.recv(1024)
    error: [Errno 10054] An existing connection was forcibly closed by the remote host

我的脚本:

Multi-server.py

import os, socket, time, threading, random

class Server:
    def __init__(self,host,port,user):
        self.port = port
        self.host = host
        self.user = user
        self.bufsize = 1024
        self.addr = (host,port)

        self.socket = socket.socket(socket.AF_INET , socket.SOCK_STREAM)
        self.socket.bind(self.addr)
        print "Server running on",host,"at port",port

        self.socket.listen(5)

def recv_loop(server,client,caddr):
    print 'Connected To',caddr

    while True:
        global clients
        name = clients[client]
        data = client.recv(1024)
        if not data:
            break
        print name + " said: " + data
    client.close()


host = 'localhost'
port = random.randint(1025,60000)
user = 'No one'

server = Server(host, port, user)

clients = {}
threads = []
while True:
    client, caddr = server.socket.accept()
    # name extraction
    name = client.recv(1024)

    clients[client] = name

    thread = threading.Thread(target=recv_loop, args=(server,client, caddr))
    thread.start()

client.py

from socket import *

host = 'localhost'
name = raw_input('Enter name: ')
port = int(raw_input('Enter server port: '))
bufsiz = 1024
addr = (host, port)

tcpClient = socket(AF_INET , SOCK_STREAM)
tcpClient.connect(addr)

# sending name
tcpClient.send(name)

while True:
    data = raw_input('> ')
    if not data:
        break
    tcpClient.send(data)
raw_input('Enter to Quit')

2 个回答

0

我没有在Python中做过套接字编程,但在客户端退出之前,你可能想要干净利落地关闭你的套接字连接。我会在客户端使用close方法。

0

问题 1

只需在客户端关闭套接字连接:

raw_input('Enter to Quit')
tcpClient.close()

问题 2

你这里遇到的是生产者消费者问题。

基本解决方案:

接收循环应该获取一个 threading.Condition,更新一个全局数组,并调用 notifyAll。发送循环应该获取这个 condition,从数组中读取数据并发送给客户端。

撰写回答