socketserver+ssl+daemon客服端连接问题!


server端代码如下:


 #! /usr/bin/env python
# coding:utf-8


from SocketServer import TCPServer, ThreadingMixIn, StreamRequestHandler,BaseRequestHandler,ThreadingTCPServer
from utility.daemon import Daemon
import ConfigParser
import os
import sys
import ssl


dir_path = os.path.dirname(__file__)  # 获得运行程序的目录路径;
configfile = os.path.join(dir_path, 'config.ini')  #获得配置文件的绝对路径

#获得证书的绝对路径:
cacrtf = os.path.join(dir_path,'ssl/ca.crt')      #根证书
certf = os.path.join(dir_path,'ssl/server.crt')    #服务器证书
keyf = os.path.join(dir_path,'ssl/server.key')    #服务器私钥
"""
在服务器端,ca_certs选项是用于验证客户端的证书。(如果CERT_REQUIRED将True,服务器将向客户提供其证书)。
事实上,在CA的证书ca_certs不发送给客户。服务器将只发送自己的证书给客户。
"""



class ReadConfig:
    """
    读取config.ini里面的配置信息
    """
    def __init__(self, configfile=''):
        self.configfile = configfile
        self.config = ConfigParser.ConfigParser()
        self.config.read(self.configfile)

    def get_node_log(self):
        """

        :return: 获得cdn日志运行日志路径
        """
        node_log = self.config.get('logfile', 'node_agent_log')
        return node_log

    def get_node_err(self):
        """

        :return:获得cdn错误日志路径
        """
        node_err_log = self.config.get('logfile', 'node_agent_error')
        return node_err_log

    def get_node_pid(self):
        """

        :return:获得cdn进程pid的路径
        """
        node_pid = self.config.get('logfile','node_pid')
        return node_pid

    def get_listen_ip(self):
        """

        :return:获得本地监听的ip地址
        """
        listen_ip = self.config.get('listen_ip','ip')
        return listen_ip

    def get_listen_port(self):
        """

        :return:获取本地监听的ip 和 端口号
        """
        listen_port = self.config.get('listen_ip','port')
        return listen_port


class MyServer(BaseRequestHandler):
    def setup(self):
        pass

    def handle(self):
        print self.request, self.client_address, self.server

        conn = self.request
        conn.sendall('连接成功..........')


    def finish(self):
        pass


class MySSL_TCPServer(TCPServer):
    def __init__(self,
                 server_address,
                 RequestHandlerClass,
                 certfile,
                 keyfile,
                 ca_certs,
                 bind_and_activate=True):


        TCPServer.__init__(self, server_address, RequestHandlerClass, bind_and_activate)
        self.certfile = certfile
        self.keyfile = keyfile
        self.ca_certs = ca_certs

    def get_request(self):
        newsocket,fromaddr = self.socket.accept()
        connstream = ssl.wrap_socket(newsocket,
                                 server_side=True,
                                 certfile=self.certfile,
                                 keyfile=self.keyfile,
                                 ca_certs=self.ca_certs)
        return connstream, fromaddr


class MySSL_ThreadingTCPServer(ThreadingMixIn, MySSL_TCPServer): pass


class testHandler(StreamRequestHandler):
    def handle(self):
        print 'Now connect form ',self.client_address[0]
        while True:
            recv_data=self.request.recv(1024)
            if not recv_data:
                continue
            else:
                if recv_data == 'hello':
                    self.wfile.write('hello.....python')
                elif recv_data == 'exit':
                    self.wfile.write('exit.....')

        # data = self.connection.recv(4096)
        # self.wfile.write(data+'server node')



class DaemonMon(Daemon):

    def run(self):
        # rc = ReadConfig(configfile)
        # ip = rc.get_listen_ip()
        # port = rc.get_listen_port()

        MySSL_ThreadingTCPServer(('%s'%ip,int(port)),testHandler,certf,keyf,cacrtf).serve_forever()




**# #测试node_agent
# rc = ReadConfig(configfile)
# ip = rc.get_listen_ip()
# port = rc.get_listen_port()
# 
# #MySSL_ThreadingTCPServer(('%s'%ip,int(port)),testHandler,certf,keyf,cacrtf).serve_forever()**


if __name__ == '__main__':
    rc = ReadConfig(configfile)
    node_log =  rc.get_node_log()
    node_err = rc.get_node_err()
    node_agent_pid = rc.get_node_pid()
    ip = rc.get_listen_ip()
    port = rc.get_listen_port()


    daemon = DaemonMon(node_agent_pid,stdout=node_log,stderr=node_err)
    if len(sys.argv) == 2:
        if 'start' == sys.argv[1]:
            daemon.start()
        elif 'stop' == sys.argv[1]:
            daemon.stop()
        elif 'restart' == sys.argv[1]:
            daemon.restart()
        else:
            print "Unknown command"
            sys.exit(2)
        sys.exit(0)
    else:
        print "usage: %s start|stop|restart" % sys.argv[0]
        sys.exit(2)

client端代码:


 #! /usr/bin/env python
# coding:utf-8




import os
import socket
import ssl
import sys

dir_path = os.path.dirname(__file__)  # 获得运行程序的目录路径;
configfile = os.path.join(dir_path, 'config.ini')  #获得配置文件的绝对路径

#获得证书的绝对路径:
cacrtf = os.path.join(dir_path,'ssl/ca.crt')      #根证书
certf = os.path.join(dir_path,'ssl/server.crt')    #服务器证书
keyf = os.path.join(dir_path,'ssl/server.key')    #服务器私钥

Tag = True

if len(sys.argv) < 2:
    print 'input error'
    sys.exit(2)
else:
    your_input = sys.argv[1]
    print '你的输入为: %s' % your_input


s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ssl_sock = ssl.wrap_socket(s, ca_certs=cacrtf, cert_reqs=ssl.CERT_REQUIRED)
ssl_sock.connect(('192.168.2.42',9999))

ssl_sock.send(your_input)
print ssl_sock.recv(4096)
ssl_sock.close()

出现问题:
如果把server端的代码不以daemon形式运行,而是以:MySSL_ThreadingTCPServer(('%s'%ip,int(port)),testHandler,certf,keyf,cacrtf).serve_forever()
形式启动,client端可以连接上去,运行没有任何问题!

但是如果server脚本以daemon方式启动,server端运行程序没有任何问题,端口也可以启动正常,但是client连接上去后,回报错:
Traceback (most recent call last):
File "./client_ssl.py", line 35, in
ssl_sock.connect(('192.168.2.42',9999))
File "/usr/lib64/python2.6/ssl.py", line 295, in connect
self.do_handshake()
File "/usr/lib64/python2.6/ssl.py", line 279, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [Errno 8] _ssl.c:492: EOF occurred in violation of protocol

截图如下:
server端:
图片描述

client报错情况:
图片描述

daemon python socketserver ssl

落花剑飞雪 10 years, 4 months ago

会不会是因为daemon的时候证书路径出问题了,直接 nc 127.0.0.1 9999 连上去试试,或者直接写成绝对路径试试。

琉璃色之月 answered 10 years, 4 months ago

应该不是证书路径问题,用daemon启动后,端口是正常的:
图片描述

Kiss丶me answered 10 years, 4 months ago

Your Answer