Python unix套接字服务器多次从客户端收到相同的数据

时间:2018-03-05 22:12:49

标签: python ruby sockets unix-socket

我试图通过unix套接字在ruby和python之间进行通信,我需要多线程python服务器来响应许多ruby客户端。所有工作都很好,除了1件事,我只从客户端发送一次消息,但服务器以某种方式收到它2次。

可能是什么问题?

这是我的python服务器代码:

import socket
import os
import threading
import time
import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# create a file handler
handler = logging.FileHandler('python_server.log')
handler.setLevel(logging.DEBUG)

# create a logging format
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

# add the handlers to the logger
logger.addHandler(handler)

class ThreadedServer(object):

    def __init__(self, socket_path):
        if os.path.exists(socket_path):
            os.remove(socket_path)

        logger.info("Opening socket...")
        self.server = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server.bind(socket_path)

    def listen(self):
        size = 1024
        logger.info("Listening...")
        try:
            while True:
                datagram, address = self.server.recvfrom(1024)
                threading.Thread(target = self.listenToClient,args = (self.server, datagram, address, logger)).start()
        finally:
            logger.info("Shutting down...")
            self.server.close()
            os.remove("/tmp/python_socket_server")
            logger.info("Done")

    def listenToClient(self, server, datagram, address, logger_obj):
        while True:
            try:
                if datagram:
                    logger_obj.info('Recieved message from client %s', address)
                    time.sleep(5)
                    server.sendto(bytes("I hear you buddy", 'UTF-8'), address)
                    logger_obj.info('Responded to client %s', address)
                else:
                    raise ValueError('Client disconnected')
            except:
                return False

if __name__ == "__main__":
    socket_path = "/tmp/python_socket_server"
    ThreadedServer(socket_path).listen()

我的红宝石客户:

require "socket"

SERVER_SOCKET = "/tmp/python_socket_server"

threads = []

5.times do 
    threads << Thread.new do 
        socket = Socket.new :UNIX, :DGRAM
        socket.bind Socket.pack_sockaddr_un("")

        socket.send("Hello server, can you hear me?\n", 0, Socket.pack_sockaddr_un(SERVER_SOCKET))
        puts socket.recvfrom(1024)

        socket.close
    end
end

threads.each { |thr| thr.join }

日志看起来像这样:

2018-03-05 22:08:43,566 - __main__ - INFO - Opening socket...
2018-03-05 22:08:43,567 - __main__ - INFO - Listening...
2018-03-05 22:08:45,572 - __main__ - INFO - Recieved message from client b'\x00025c0'
2018-03-05 22:08:45,573 - __main__ - INFO - Recieved message from client b'\x00025c1'
2018-03-05 22:08:45,573 - __main__ - INFO - Recieved message from client b'\x00025c2'
2018-03-05 22:08:45,574 - __main__ - INFO - Recieved message from client b'\x00025c3'
2018-03-05 22:08:45,574 - __main__ - INFO - Recieved message from client b'\x00025c4'
2018-03-05 22:08:50,574 - __main__ - INFO - Responded to client b'\x00025c3'
2018-03-05 22:08:50,575 - __main__ - INFO - Recieved message from client b'\x00025c3'
2018-03-05 22:08:50,577 - __main__ - INFO - Responded to client b'\x00025c1'
2018-03-05 22:08:50,577 - __main__ - INFO - Recieved message from client b'\x00025c1'
2018-03-05 22:08:50,577 - __main__ - INFO - Responded to client b'\x00025c2'
2018-03-05 22:08:50,577 - __main__ - INFO - Recieved message from client b'\x00025c2'
2018-03-05 22:08:50,578 - __main__ - INFO - Responded to client b'\x00025c0'
2018-03-05 22:08:50,578 - __main__ - INFO - Recieved message from client b'\x00025c0'
2018-03-05 22:08:50,579 - __main__ - INFO - Responded to client b'\x00025c4'
2018-03-05 22:08:50,579 - __main__ - INFO - Recieved message from client b'\x00025c4'
2018-03-05 22:08:56,437 - __main__ - INFO - Shutting down...
2018-03-05 22:08:56,438 - __main__ - INFO - Done

1 个答案:

答案 0 :(得分:2)

问题出在while True:方法开头的listenToClient。 (如果您只删除该行,它应该按预期工作。)

您已经在listen中获得了数据报,因此您的listenToClient只需要处理它并将数据返回到另一端。 (以这种方式,它应该被称为handleClientRequestrespondToClient或类似,可能更合适。)

while True:到位时,它将回到该循环的开始,其中datagram仍设置为相同的值,因此它试图再次回复另一方。 (那些线程可能会卡在那里,因为另一方停止接收。)

我希望有所帮助!