I am trying to communicate between ruby and python through unix sockets, and i need multithreaded python server to respond to many ruby clients. All work fine except 1 thing, that i send message from client only once, but the server recieves it 2 times somehow.
What maybe the problem?
Here's my python server code:
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()
My ruby client:
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 }
And the log looks like this:
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
The problem is with the while True:
at the start of your listenToClient
method. (If you just remove that line, it should work as you expect it to.)
You get a datagram already in listen
, so your listenToClient
only needs to handle it and return data to the other end. (In that way, it should probably be called handleClientRequest
or respondToClient
or similar, that might be more appropriate.)
With the while True:
in place, it's going back to the start of that loop, where datagram
is still set to the same value, so it's trying to reply to the other side once again. (Those threads probably get stuck there, since the other side stopped receiving.)
I hope that helps!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.