标签: socketserver

从ThreadingTCPServer正常关闭

我已经基于这里的示例创建了一个运行ThreadingTCPServer的简单测试应用程序(Python 2.6.1).如果客户端发送命令"bye",我想关闭服务器并从应用程序中彻底退出.退出部分工作正常,但当我尝试重新运行应用程序时,我得到:

socket.error: [Errno 48] Address already in use
Run Code Online (Sandbox Code Playgroud)

我尝试了这里给出的解决方案来设置套接字选项,但这似乎没有帮助.我已尝试各种方法关闭服务器,但总是得到相同的错误.

知道我做错了什么吗?

import SocketServer
import socket
import sys
import threading
import time

class RequestHandler(SocketServer.BaseRequestHandler):

    def setup(self):
        print("Connection received from %s" % str(self.client_address))
        self.request.send("Welcome!\n")

    def handle(self):
        while 1:
            data = self.request.recv(1024)
            if (data.strip() == 'bye'):
                 print("Leaving server.")
                 self.finish()
                 self.server.shutdown()
                 # None of these things seem to work either
                 #time.sleep(2)
                 #del self.server.socket
                 #self.server.socket.shutdown(socket.SHUT_WR)
                 #self.server.socket.close()
                 #self.server.server_close()
                 break


    def finish(self):
        self.request.send("Goodbye!  Please come back soon.")

if __name__ == "__main__":
       server = …
Run Code Online (Sandbox Code Playgroud)

python tcp socketserver

5
推荐指数
1
解决办法
4614
查看次数

Python SocketServer.TCPServer 请求

我一直在玩Python的SocketServer:

#!/usr/bin/python

import SocketServer

class EchoHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        data=self.request.recv(1024)
        self.request.send(data)

HOST, PORT = "localhost", 9999
server = SocketServer.TCPServer((HOST, PORT), TCPEchoServer)
server.serve_forever() 
Run Code Online (Sandbox Code Playgroud)

通过阅读源代码,我知道作为参数接收并RequestHandler.__init__()在.requestself.request

在哪里可以找到该request对象的规格?

python socketserver

5
推荐指数
1
解决办法
3066
查看次数

退出/崩溃时关闭服务器套接字

我正在学习如何在python中使用套接字,并且经常当我的程序崩溃或者我在Ctrl + C时服务器套接字以某种方式继续监听端口.这显然会阻止程序在再次启动时监听该端口,因此我必须不断更改它.

我猜我需要在某处做socket.close(),但在哪里?

python sockets socketserver

5
推荐指数
1
解决办法
8206
查看次数

BaseRequestHandler类有没有办法成为有状态的?

简短问题
使用下面的示例,是否有一种Pythonic方法my_object与BaseRequestHandler类共享实际实例?

背景
根据定义,BaseRequestHandler类为每个请求创建一个新实例.因此,我正在努力寻找一种解决方案来解决如何将handle()函数中的数据传回ProtocolInterface实例的问题.请注意,如果我需要执行handle()除print到stdout以外的操作,这可能是错误的方法.

在这个时间点,我不相信全局变量会my_object传递,因为传入并且预计会经常更改(这就是为什么handle()需要看到它.要查看示例客户端(发送伪造数据),请参阅我的其他SO问题.我认为我面临的最大问题是套接字服务器在后台线程中运行.

我想做什么的例子

class ProtocolHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        while(1):
            self.data = self.request.recv(1024)
            if self.data == '':
                break
            self.request.send("Success") 
            self.my_object.success = True#  <--- How can I share my_object's instance?

class ProtocolInterface():
    def __init__(self, obj, host='127.0.0.1', port=8000, single_connection=False):
        self.my_object = obj # <--- This ideally is the same instance seen in ProtocolHandler
        self.host = host
        self.port = port

        # Create the socket server to process in …
Run Code Online (Sandbox Code Playgroud)

python sockets namespaces socketserver

5
推荐指数
1
解决办法
2503
查看次数

如果TCPServer在另一个线程中运行,Python 2不处理信号

在使用标准库时,我发现python2和python3之间存在一些奇怪的区别.如果我尝试在python2中捕获信号,而TCPServer在不同的线程中运行,则信号不会被处理,但在python3中它确实如此.

这是一个重现问题的脚本

import signal
import threading
import sys 
if sys.version_info > (3,0):
    from socketserver import TCPServer, BaseRequestHandler
else:
    from SocketServer import TCPServer, BaseRequestHandler

def shutdown(signum, frame):
    print("Shutting down server thread")
    server.shutdown()

server = TCPServer(
    ('127.0.0.1', 7654),
    BaseRequestHandler
)
signal.signal(signal.SIGTERM, shutdown)
signal.signal(signal.SIGINT, shutdown)
server_thread = threading.Thread(target=server.serve_forever)
print("Starting server thread")
server_thread.start()
print("Waiting for server thread to shut down")
server_thread.join()
print("Server thread terminated")
Run Code Online (Sandbox Code Playgroud)

这是python3的输出:

Starting server thread
Waiting for server thread to shut down
^CShutting down server thread
Server thread terminated
Run Code Online (Sandbox Code Playgroud)

这是来自python2:

Starting …
Run Code Online (Sandbox Code Playgroud)

python signals socketserver

5
推荐指数
1
解决办法
1250
查看次数

关闭 SIG* 上的 SocketServer

我对如何正确关闭我正在使用的非常简单的服务器感到困惑。

我想这应该足够了:

#!/usr/bin/python

import signal
import myhandler
import SocketServer

def terminate(signal, frame):
    print "terminating on %s at %s"
    server.shutdown()

if __name__ == "__main__":

    signal.signal(signal.SIGTERM, terminate)

    server = SocketServer.TCPServer(("localhost", 9999), myhandler.MyHandler)

    server.serve_forever()
Run Code Online (Sandbox Code Playgroud)

服务器工作正常,但是当我向它抛出 SIGTERM 时,它只会打印terminating on 15 at ...但不会真正关闭(即关闭所有套接字并退出)。

现在 pydoc 解释了它

#!/usr/bin/python

import signal
import myhandler
import SocketServer

def terminate(signal, frame):
    print "terminating on %s at %s"
    server.shutdown()

if __name__ == "__main__":

    signal.signal(signal.SIGTERM, terminate)

    server = SocketServer.TCPServer(("localhost", 9999), myhandler.MyHandler)

    server.serve_forever()
Run Code Online (Sandbox Code Playgroud)

但这就是我迷失的地方,因为我什至无法理解线程编程。现在我只需要一个简单的 TCP 回显服务器,我可以killall随时启动该服务器(由于剩余的监听套接字而现在失败)。

那么实现这一目标的正确方法是什么?

python multithreading socketserver

5
推荐指数
1
解决办法
3512
查看次数

SocketServer ThreadingMix中server_thread的用途

在异步(线程)SocketServer http://docs.python.org/2/library/socketserver.html的示例中,启动服务器线程(称为 server_thread),为每个请求启动新线程。由于捕获键盘中断时出现一些问题,我开始寻找类似的代码,发现不使用服务器线程时没有明显的区别,但 ctrl-c 实际上有效。

尽管我的代码有效,但我很想知道

1)为什么在使用 server_thread 时,简单的“尝试”捕获 KeyboardInterrupt 不起作用?

2)与我的稍微简单的示例相比,示例中的 server_thread 有什么好处?

从python SocketServer示例来看,在try中捕获键盘中断不起作用:

if __name__ == "__main__":
    server = ThreadedTCPServer(serverAddr, SomeCode)
<snip>
    # Start a thread with the server -- that thread will then start one
    # more thread for each request
    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.start()
Run Code Online (Sandbox Code Playgroud)

我的更简单的例子是 ctrl-c 有效。

if __name__ == "__main__":
    server = ThreadedTCPServer(serverAddr, SomeCode)
    try:
        server.serve_forever()
        print "ctrl-c to exit"
    except KeyboardInterrupt:
        print  "interrupt received, exiting"
        server.shutdown() 
Run Code Online (Sandbox Code Playgroud)

python socketserver python-2.7

5
推荐指数
1
解决办法
2966
查看次数

希望在 Python 中模拟 socat 的功能

我需要使用 python 将字符串发送到本地主机上的特定端口。

我可以通过在命令行上使用 socat 来实现这一点,如下所示:

cat <text file containing string to send> | socat stdin tcp-connect:127.0.0.1:55559
Run Code Online (Sandbox Code Playgroud)

我不想将 socat 命令作为子命令运行,所以我想知道如何使用 python 模块使其工作。

我尝试使用套接字失败了。下面是我使用的一个脚本,它没有达到预期的效果。

    import socket
    HOST, PORT = "127.0.0.1", 55559
    jsonString = '{"name":"VideoStreamStatus","parameters":{"name":"video_0_0"}}'

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

    try:
        # Connect to server and send data
        print "Attempting connection"
        sock.connect((HOST, PORT))
        print "Sending json string"
        sock.sendall(jsonString)
        print "String sent"

    finally:
        sock.close()

    print "Sent:     {}".format(jsonString)
Run Code Online (Sandbox Code Playgroud)

python 脚本执行时没有任何错误,但对接收 socat 数据的进程没有任何影响。Python脚本输出如下:

    Attempting connection
    Sending json string
    Sent:     {"name":"VideoStreamStatus","parameters":{"name":"video_0_0"}}
Run Code Online (Sandbox Code Playgroud)

我在套接字脚本中做错了什么,或者我可以在 Python 中使用不同的方法吗?我很感激任何建议。谢谢。

编辑:我尝试向其发送字符串的服务器是 C++ 程序的一部分,该程序使用 …

python socat socketserver

5
推荐指数
1
解决办法
4641
查看次数

向SocketServer添加SSL支持

我有一个基于的服务器ThreadingTCPServer.现在我想要为该服务器添加SSL支持.没有SSL它工作正常,但使用SSLv3我无法将客户端连接到服务器,它总是抛出一个异常:Error 111 Connection Refused.错误是该端口上没有SSL服务器.

我根据Stackoverflow上的示例添加了SSL支持.这是我的代码:

服务器:

class BeastServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):

    def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
        SocketServer.BaseServer.__init__(self, server_address,
                                                        RequestHandlerClass)
        ctx = SSL.Context(SSL.SSLv3_METHOD)
        cert = 'server.pem'
        key = 'key.pem'
        ctx.use_privatekey_file(key)
        ctx.use_certificate_file(cert)
        self.socket = SSL.Connection(ctx, socket.socket(self.address_family,
                                                        self.socket_type))
        if bind_and_activate:
        #self.server_bind()
        #self.server_a
Run Code Online (Sandbox Code Playgroud)

客户:

class Client(object) :

    def verbinden (self, ip_) :

        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        ssl_sock = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED,
                    ssl_version=ssl.PROTOCOL_SSLv3, ca_certs='server.pem')
        ssl_sock.connect((ip_, 10012))

        return ssl_sock
Run Code Online (Sandbox Code Playgroud)

密钥和证书文件是使用开放SSL创建的.我希望有人能告诉我问题是什么.

谢谢你的帮助

最好的问候帕特里克

python ssl socketserver

4
推荐指数
2
解决办法
1万
查看次数

来自java客户端的Python套接字recv

我有一个简单的python tcp服务器(我正在使用SocketServer类)的问题,必须从Java客户端接收数据.

这里是服务器端代码:

class ServerRequestHandler(SocketServer.BaseRequestHandler):
    [...]
    def handle(self):
        requestCode = struct.unpack('>i', self.request.recv(4))[0]
        [...]
    [...]
Run Code Online (Sandbox Code Playgroud)

这里有客户:

addr = InetAddress.getByName(hostname);
SocketAddress sockaddr = new InetSocketAddress(addr, port);
clientSocket = new Socket();
clientSocket.connect(sockaddr, timeoutMs);
clientSocketDataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
int   requestCode = 1;
clientSocketDataOutputStream.writeInt(requestCode);
clientSocketDataOutputStream.flush();
Run Code Online (Sandbox Code Playgroud)

我启动Python服务器然后尝试执行必须向服务器发送整数的客户端.

在服务器端,Python引发异常,因为该recv(4)函数不读取4个字节,它只返回一个字节.

我的java客户端实际上正确地发送了4个字节,如果我尝试调用recv(1)4次它正确地读取4个字节.

我试着编写一个Python客户端来执行我的java客户端的相同操作,在这种情况下服务器recv(4)运行良好.

如何解决这个问题呢?我想实现一个简单的python buffered reader function,它逐字节地从socket读取,但我确信存在一个更智能的解决方案.

python java sockets socketserver

4
推荐指数
1
解决办法
1429
查看次数