gpt4 book ai didi

Python 访问 BaseRequestHandler

转载 作者:可可西里 更新时间:2023-11-01 02:47:50 25 4
gpt4 key购买 nike

我的代码基本上需要启动一个带有客户端的简单聊天服务器。服务器和客户端可以相互来回交谈的地方。我已经得到了正确实现的一切,但我无法弄清楚如何在我完成时关闭服务器。 (我知道它是 ss.shutdown())。

我想根据两者之间共享的关键字(例如 “bye”)立即结束,但我不知道是否可以通过某种方式向我的 SocketServerBaseRequestHandlershutdown() 每当它收到消息时。

最终,我的目标是结合 Tkinter 来制作一个 GUI,但我想先让其他一切正常工作,这是我第一次在 Python 中处理套接字。

from sys import argv, stderr
from threading import Thread
import socket
import SocketServer
import threading
import sys

class ThreadedRecv(Thread):
def __init__(self,socket):
Thread.__init__(self)
self.__socket = socket
self.__message = ''
self.__done = False
def recv(self):
while self.__message.strip() != "bye" and not self.getStatus():
self.__message = self.__socket.recv(4096)
print 'received',self.__message
self.setStatus(True)

def run(self):
self.recv()

def setStatus(self,status):
self.__done = status

def getStatus(self):
return self.__done

class ThreadedSend(Thread):
def __init__(self,socket):
Thread.__init__(self)
self.__socket = socket
self.__message = ''
self.__done = False
def send(self):
while self.__message != "bye" and not self.getStatus():
self.__message = raw_input()
self.__socket.send(self.__message)
self.setStatus(True)

def run(self):
self.send()

def setStatus(self,status):
self.__done = status

def getStatus(self):
return self.__done



class HostException(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)

class EchoServer(SocketServer.BaseRequestHandler):
def setup(self):
print self.client_address, 'is connected!'
self.request.send('Hello ' + str(self.client_address) + '\n')
self.__done = False
def handle(self):

sender = ThreadedSend(self.request)
recver = ThreadedRecv(self.request)
sender.start()
recver.start()
while 1:
if recver.getStatus():
sender.setStatus(True)
break
if sender.getStatus():
recver.setStatus(True)
break

def finish(self):
print self.client_address, 'disconnected'
self.request.send('bye client %s\n' % str(self.client_address))
self.setDone(True)

def setDone(self,done):
self.__done = done

def getDone(self):
return self.__done



def setup(arg1, arg2, arg3):
server = False
defaultPort,defaultHost = 2358,"localhost"
hosts = []
port = defaultPort
serverNames = ["TRUE","SERVER","S","YES"]
arg1 = arg1.upper()
arg2 = arg2.upper()
arg3 = arg3.upper()
if arg1 in serverNames or arg2 in serverNames or arg3 in serverNames:
server = True
try:
port = int(arg1)
if arg2 != '':
hosts.append(arg2)
except ValueError:
if arg1 != '':
hosts.append(arg1)
try:
port = int(arg2)
if arg3 != '':
hosts.append(arg3)
except ValueError:
if arg2 != '':
hosts.append(arg2)
try:
port = int(arg3)
except ValueError:
if arg3 != '':
hosts.append(arg3)
port = defaultPort

for sn in serverNames:
if sn in hosts:
hosts.remove(sn)

try:
if len(hosts) != 1:
raise HostException("Either more than one or no host "+ \
"declared. Setting host to localhost.")
except HostException as error:
print error.value, "Setting hosts to default"
return (server,defaultHost,port)

return (server,hosts[0].lower(),port)

def main():
bufsize = 4096
while len(argv[1:4]) < 3:
argv.append('')
settings = setup(*argv[1:4])
connections = (settings[1],settings[2])
print connections
if not settings[0]:
try:
mySocket = socket.socket(socket.AF_INET,\
socket.SOCK_STREAM)
except socket.error, msg:
stderr.write("[ERROR] %s\n" % msg[1])
sys.exit(1)
try:
mySocket.connect(connections)
except socket.error, msg:
stderr.write("[ERROR] %s\n" % msg[1])
sys.exit(2)

message = ""
print "Enter a message to send to the server. "+\
"Enter \"bye\" to quit."
sender = ThreadedSend(mySocket)
recver = ThreadedRecv(mySocket)
sender.start()
recver.start()
while 1:
if sender.getStatus():
recver.setStatus(True)
break
if recver.getStatus():
sender.setStatus(True)
break

else:
xserverhandler = EchoServer
serversocket = SocketServer.ThreadedTCPServer(\
connections,xserverhandler)
server_thread = Thread(target = serversocket.serve_forever)
server_thread.setDaemon(True)
server_thread.start()
# I would like to shut down this server whenever
# I get done talking to it.
"""while 1:
if xserverhandler.getDone():
print 'This is now true!'
serversocket.shutdown()
break"""

if __name__ == '__main__':
main()

是的,我知道 setup() 现在对于 try 和 catch 来说是一个糟糕的函数,但它现在可以工作,所以我打算稍后修复它。

我的问题基本上是:如何让服务器根据收到的消息实际结束?如果可能,有没有办法在 Request Handler 启动后访问它?

最佳答案

请修复您的代码以使其正常工作,并提供一些使用方法。你需要添加

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass

因为 SocketServer 实际上并不包含该类(至少在我的 2.6 或 2.7 版本中不包含)。相反,它是来自 SocketServer definition 的示例.

请包括一个如何启动/使用代码的示例。在这种情况下,要启动服务器,您需要执行以下操作:

ss.py SERVER localhost 8001

和客户端作为

ss.py localhost 8001

如果您这样做,那么您将无法执行 server_thread.setDaemon(True),因为没有其他线程在运行,这意味着服务器将立即退出。

完成后,解决方案是在 EchoServer.handle 方法的 self.server.shutdown() insdie 中添加一个(或两个)调用,例如:

    while 1:
if recver.getStatus():
sender.setStatus(True)
self.server.shutdown()
break

但是,我无法让它发挥作用,我认为这是因为我继承了错误的东西,或者对你所做的事情猜错了。

你应该做的是搜索其他用 Python 做过聊天服务器的人。使用谷歌我找到了http://www.slideshare.net/didip/socket-programming-in-python当然还有其他人。

此外,如果您打算混合使用 GUI 和线程编程,那么您应该查看基于此的示例。当我搜索“tkinter chat”时,有很多点击。另外,您可能想看看 twisted,它已经解决了很多这样的问题。

什么问题?嗯,例如,您可能需要一个 SO_REUSEADDR 套接字选项。

关于Python 访问 BaseRequestHandler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1578932/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com