Python subprocess connection refused in ros melodic - python

I want to communicate using subprocess in ros melodic package.
Because ros uses python2 as default, I had some python version problems with python3 libraries.
That's why I decided to use a subprocess.
Here are two of my codes: first is a node of ros(as a client), second is a python3 file as a server.
- Client(image_bus.py)
#!/usr/bin/env python
import rospy
import cv2
import numpy as np
import os
import subprocess
from cv_bridge import CvBridge, CvBridgeError
from std_msgs.msg import String
from sensor_msgs.msg import Image
from json_socket import Client
HOST_IP = "127.0.0.1"
HOST_PORT = 9989
class ImageBus:
def __init__(self):
self.sub_video_capture = rospy.Subscriber('/video_capture', Image, self.send_to_face_detector)
self.cvb = CvBridge()
self.rate = rospy.Rate(2)
self.client = Client()
def send_to_face_detector(self, image):
try:
cv_image = self.cvb.imgmsg_to_cv2(image, "bgr8")
except CvBridgeError as e:
print(e)
filename = os.path.dirname(os.path.abspath(__file__)) + "/face_detector.py"
p = subprocess.Popen(["python3", filename])
print("p : ", p)
self.rate.sleep()
# client = Client()
c = self.client.connect(HOST_IP, HOST_PORT)
send_data = {}
send_data['video_cap'] = cv_image
self.client.send(send_data)
recv_data = self.client.recv()
self.rate.sleep()
self.client.close()
if __name__ == '__main__':
rospy.init_node('ImageBus', anonymous=False)
ib = ImageBus()
try:
rospy.spin()
except rospy.ROSInterruptException:
pass
Server(face_detector.py)
import cv2
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import math
from sklearn.decomposition import PCA
import os
import glob
from jsonsocket import Server
BIND_IP = "127.0.0.1"
BIND_PORT = 9989
class FaceDetector:
def __init__(self):
self.socket = Server(BIND_IP, BIND_PORT)
# Some Codes Here
def check_face(self, frame):
# Some codes Here
return boxed_frame
if __name__=="__main__":
fd = FaceDetector()
fd.socket.accept()
while True:
print("SERVER")
recv_image = fd.socket.recv()
if not recv_image:
break
video_cap = recv_data['video_cap']
face_detected_image = fd.check_face(video_cap)
send_image = {}
send_image['face_detected_image'] = face_detected_image
fd.socket.send(send_image)
fd.socket.close()
And below code is my jsonsocket.py.
import socket
import json
def _send(socket, send_data):
json_data = json.JSONEncoder().encode(send_data)
socket.sendall(json_data.encode())
def _recv(socket):
recv_data = socket.recv(4096)
json_data = json.loads(recv_data.decode())
return json_data
class Server(object):
backlog =1
client =None
def __init__(self, host, port):
self.socket = socket.socket()
self.socket.bind((host, port))
self.socket.listen(self.backlog)
def __del__(self):
self.close()
def accept(self):
if self.client:
self.client.close()
self.client, self.client_addr =self.socket.accept()
return self
def send(self, data):
if not self.client:
raise Exception('Cantnot send data, no client is connected.')
_send(self.client, data)
return self
def recv(self):
if not self.client:
raise Exception('Cannot receive data, no client is connected.')
return _recv(self.client)
def close(self):
if self.client:
self.client.close()
self.client =None
if self.socket:
self.socket.close()
self.socket =None
class Client(object):
socket =None
def __del__(self):
self.close()
def connect(self, host, port):
self.socket = socket.socket()
self.socket.connect((host, port))
return self
def send(self, data):
if not self.socket:
raise Exception('You have to connect first before sending data.')
_send(self.socket, data)
return self
def recv(self):
if not self.socket:
raise Exception('You have to connect first before receving data.')
return _recv(self.socket)
def close(self):
if self.socket:
self.socket.close()
self.socket =None
When I roslaunch this package with my launch file, then It outputs:
File "/catkin_ws/src/jetson/src/image_bus.py", line 37, in send_to_face_detector
c = self.client.connect(HOST_IP, HOST_PORT)
File "/catkin_ws/src/jetson/src/json_socket.py", line 67, in connect
self.socket.connect((host, port))
File "/usr/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
error: [Errno 111] Connection refused
How can I solve this problem?
I tried to change the port number, change the variable name, check where the problem occurs exactly. However, I couldn't find out.
Help me, please.
Thank you.

Stripped down, this looks purely like an issue with your socket code: you're trying to connect() and the other side isn't allowing it.
I notice your socket() calls, however, are empty; try socket.socket(socket.AF_INET, socket.SOCK_DGRAM) instead of the empty call.
Try isolating/testing just the server/client, there are other questions that address issues with socket connections.

Related

asyncio.gather() is starting first two tasks but not the third one

I have a python function that is supposed to send packet asynchronously in a loop.
import asyncio
import logging
import pickle
from time import sleep
from decoder import decode, encode
from socket import *
UDP_PORT_NUMBER = 44006
HOST_ADDRESS = "192.168.204.139"
server_address = (HOST_ADDRESS, UDP_PORT_NUMBER)
def get_data_packet():
with open('../packets/packet_15', mode='rb') as fpt:
packet = pickle.load(fpt, encoding='bytes')
return packet
class GcuUdpClient:
#staticmethod
async def send_packets():
data = get_data_packet()
client_socket = socket(AF_INET, SOCK_DGRAM)
client_socket.sendto(data, server_address)
print('sending data packets')
await asyncio.sleep(5)
I have another python program that calls this class, along with two other classes.
import asyncio
from http_server import PostServer
from grpc_server import GrpcServer
from gcu_udp_client import GcuUdpClient
async def main():
await asyncio.gather(GrpcServer.run(), PostServer.run_server(), GcuUdpClient.send_packets())
if __name__ == '__main__':
asyncio.run(main())
This code starts up the first two meaning
GrpcServer.run()
and
PostServer.run_server()
However I can't get the last one started, to send out the packets. What am I missing.
Adding the code for http_server.py
import threading
import zlib
from http import HTTPStatus
from http.server import HTTPServer, BaseHTTPRequestHandler
from io import BytesIO
from socket import *
from time import sleep
#from GCUSimulator.generated.GDataPayload_pb2 import GDataPayload
from generated.GDataPayload_pb2 import GDataPayload
HTTP_PORT_NUMBER = 8085
HTTP_SERVER_IP="192.168.204.1"
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def __init__(self, *args, **kwargs):
self.subscribed = False
super(SimpleHTTPRequestHandler, self).__init__(*args, *kwargs)
def do_GET(self):
self.send_response(200)
self.end_headers()
def do_POST(self):
content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
post_data = self.rfile.read(content_length) # <--- Gets the data itself
print("POST Path: {0} Headers: {1} Body: {2}".
format(str(self.path), str(self.headers), post_data.decode('utf-8')))
if str(self.path) == '/setSubscriber.php':
message = "Subscription Result:Subscribed,APIVersion:1.0.0"
self.send_response(HTTPStatus.OK)
self.end_headers()
self.wfile.write(message.encode('utf-8'))
self.subscribed = True
elif str(self.path) == '/removeSubscriber.php':
self.send_response(HTTPStatus.OK)
self.end_headers()
self.subscribed = False
def get_subscription_status(self):
return self.subscribed
class PostServer:
#staticmethod
async def run_server(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler, addr=HTTP_SERVER_IP, port=HTTP_PORT_NUMBER):
server_address = (addr, port)
print('Http Post server : {0}:{1}'.format(addr, port))
httpd = server_class(server_address, handler_class)
await httpd.serve_forever()
Adding the code for grpc_server.py
from concurrent import futures
import grpc
from generated import guidance_grpc_service_definitions_pb2_grpc
from gcu.ops_station_services import OPSStationServices
GRPC_PORT_NUMBER = 12074
class GrpcServer:
#staticmethod
async def run():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
guidance_grpc_service_definitions_pb2_grpc.add_OpRPCServicesServicer_to_server(OServices(), server)
server.add_insecure_port('[::]:{0}'.format(GRPC_PORT_NUMBER))
print('Grpc Server : {0}:{1}'.format('localhost', GRPC_PORT_NUMBER))
server.start()
# server.wait_for_termination()

uncaptured python exception, closing channel class 'TypeError'>:a bytes-like object is required, not 'str'

I want to send several different data simultaneously between 2 computers on a network. The code I wrote is below, but when I run the server and client python files, I get some errors and I haven't been able to solve these errors yet. Can you help me by reviewing the code?
Server.py
import asyncore
import socket
import time
import logging
import json
class Server(asyncore.dispatcher):
def __init__(self, host, port):
self.logger = logging.getLogger('SERVER')
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind(('', port))
self.listen(confjson.get('SERVER_QUEUE_SIZE', None))
self.logger.debug('binding to {}'.format(self.socket.getsockname()))
def handle_accept(self):
socket, address = self.accept()
self.logger.debug('new connection accepted')
EchoHandler(socket)
class EchoHandler(asyncore.dispatcher_with_send):
def handle_read(self):
msg = self.recv(confjson.get('RATE', None))
self.out_buffer = msg
self.out_buffer += ' server recieve: {}'.format(time.time())
if not self.out_buffer:
self.close()
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG,
format='%(name)s: %(message)s',
)
with open('SOCKET\config.json', 'r') as jfile:
confjson = json.load(jfile)
try:
logging.debug('Server start')
server = Server(confjson.get('HOST', None),
confjson.get('PORT', None))
asyncore.loop()
except:
logging.error('Something happened,\n'
'if it was not a keyboard break...\n'
'check if address taken, '
'or another instance is running. Exit')
finally:
logging.debug('Goodbye')
I am getting this error for server.py
**error: uncaptured python exception, closing channel <__main__.EchoHandler 192.168.1.108:49729 at 0x2b8b12998a0> (<class 'TypeError'>:can't concat str to bytes [C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.752.0_x64__qbz5n2kfra8p0\lib\asyncore.py|read|90] [C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.752.0_x64__qbz5n2kfra8p0\lib\asyncore.py|handle_read_event|427] [c:\Users\Aydin\Desktop\ARAYUZ\SOCKET\server2.py|handle_read|32])**
Client.py
import asyncore
import socket
import time
import logging
import json
class Client(asyncore.dispatcher_with_send):
def __init__(self, host, port, message, pk):
self.logger = logging.getLogger('CLIENT')
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.host = host
self.port = port
self.connect((host, port))
self.out_buffer = message
self.clientID = pk
self.logger.debug('Connected #{}'.format(self.clientID))
def handle_close(self):
self.close()
def handle_read(self):
rec_msg = self.recv(confjson.get('RATE', None))
self.logger.debug('#{}, {} back at client {}'.format(self.clientID,
rec_msg,
time.time()
)
)
self.close()
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG,
format='%(name)s: %(message)s',
)
with open('config.json', 'r') as jfile:
confjson = json.load(jfile)
clients = []
for idx in range(confjson.get('SOCKET_AMOUNT', None)):
msg = "Start: {}".format(time.time())
clients.append(Client(confjson.get('HOST', None),
confjson.get('PORT', None),
msg,
idx)
)
start = time.time()
logging.debug(
'Starting async loop for all connections, unix time {}'.format(start))
asyncore.loop()
logging.debug('{}'.format(time.time() - start))
I get this error for client.py.
error: uncaptured python exception, closing channel <_main_.Client connected 192.168.1.106:42478 at 0x16553e9ec40> (<class 'TypeError'>:a bytes-like object is required, not 'str' [C:\Users\tural\AppData\Local\Programs\Python\Python38\lib\asyncore.py|write|91]
How can I fix this problems ?

Python : threads can only be started once

I'm writing a simple chat, for the moment it just connect an user.
bootchat/
--server.py
--client.py
--libbootchat/
--bootchat_connection.py
--bootchat_server.py
--bootchat_user.py
Code:
client.py
# imports
import libbootchat.bootchat_user as user
import socket
print("Welcome on BootChat")
nickname = input("nickname : ")
bootchat_user = user.BootchatUser(nickname)
server.py
# imports
import socket
import signal
import libbootchat.bootchat_server as server
import libbootchat.bootchat_connection as connection
print("Starting server...")
bootchat_server = server.BootchatServer()
while True:
bootchat_server.accept_connection()
bootchat_server.start()
bootchat_connection.py
class BootchatConnection():
def __init__(self, socket, informations=None):
self.socket = socket
if informations:
self.ip = informations[0]
self.port = informations[1]
def connect_to_server(self, ip, port):
self.socket.connect((ip, port))
def send_to_server(self, msg):
self.socket.send(msg.encode())
def recv_from_client(self):
return self.socket.recv(1024).decode()
bootchat_user.py
from libbootchat.bootchat_connection import BootchatConnection
import socket
class BootchatUser:
nb_users = 0
def __init__(self, nickname):
self.nickname = nickname
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.bootchat_connection = BootchatConnection(connection)
self.bootchat_connection.connect_to_server("localhost", 15297)
self.send_message(nickname)
def send_message(self, msg):
self.bootchat_connection.send_to_server(msg)
bootchat_server.py
import socket
from threading import Thread
from libbootchat.bootchat_connection import BootchatConnection
class BootchatServer(Thread):
def __init__(self):
Thread.__init__(self)
self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.listener.bind(('', 15297))
self.listener.listen(5)
def accept_connection(self):
socket, infos = self.listener.accept()
self.bootchat_connection = BootchatConnection(socket, infos)
def run(self):
print("[INFO] New user connected from {}".format(self.bootchat_connection.ip))
nickname = self.bootchat_connection.recv_from_client()
print("[INFO] User from {} now logged at {}".format(self.bootchat_connection.ip, nickname))
Problem:
I start server and i start a first client, and I send a nickname and I have no problems, my server print correctly "New user connected...", but after, I start a second client, and I have an error. This is the output of my server.py :
Starting server...
[INFO] New user connected from 127.0.0.1
[INFO] User from 127.0.0.1 now logged at Alex
Traceback (most recent call last):
File "server.py", line 14, in <module>
bootchat_server.start()
File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/threading.py", line 840, in start
raise RuntimeError("threads can only be started once")
RuntimeError: threads can only be started once
Any ideas ? Thank you
Generate a new thread for each connection:
class BootchatServer(object):
def __init__(self):
self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.listener.bind(('', 15297))
self.listener.listen(5)
def accept_connection(self):
socket, infos = self.listener.accept()
connection = BootchatConnection(socket, infos)
thread = Thread(target=self.process_connection, args=(connection,))
thread.start()
def process_connection(self, connection):
print("[INFO] New user connected from {}".format(connection.ip))
nickname = connection.recv_from_client()
print("[INFO] User from {} now logged at {}".format(connection.ip, nickname))
print("Starting server...")
bootchat_server = server.BootchatServer()
while True:
bootchat_server.accept_connection()

How to get the modbus_tk master's IP?

I write a slave.py(server) base on modbus_tk(https://github.com/ljean/modbus-tk).
Then,I use the client tools to connect the slave,It's OK.
And now,I want to get which master(client) access to me,I want to get source IP and port.
I find the key point 'client, address = self._sock.accept()' in function _do_run(self) in Class TcpServer(server) ,modbus_tcp.py.
I tried some methods, but it didn't work.
slave.py
import modbus_tk
import modbus_tk.modbus_tcp as modbus_tcp
import modbus_tk.defines as mdef
import threading
import sys
from lxml import etree
logger = modbus_tk.utils.create_logger(name='console', record_format='%(message)s')
server = modbus_tcp.TcpServer(port=502,address='0.0.0.0')
class Modbus_server(object):
def main(self):
try:
logger.info("running...")
logger.info("enter 'quit' for closing the server")
server.start()
self.config_slaves()
while True:
cmd = sys.stdin.readline()
if cmd.find('quit')==0:
#when input"quit",the program exit!
sys.stdout.write('bye-bye\r\n')
sys.exit(0)
finally:
server.stop()
#get slave configuration
def config_slaves(self):
dom = etree.parse('modbus.xml')
slaves = dom.xpath('//modbus/slaves/*')
try:
for s in slaves:
slave_id = int(s.attrib['id'])
slave = server.add_slave(slave_id)
logger.debug('Added slave with id %s.', slave_id)
for b in s.xpath('./blocks/*'):
name = b.attrib['name']
request_type = eval('mdef.' + b.xpath('./type/text()')[0])
start_addr = int(b.xpath('./starting_address/text()')[0])
size = int(b.xpath('./size/text()')[0])
slave.add_block(name, request_type, start_addr, size)
logger.debug(
'Added block %s to slave %s. '
'(type=%s, start=%s, size=%s)',
name, slave_id, request_type, start_addr, size)
logger.info('modbus initialized')
except (Exception) as e:
logger.info(e)
modbus=Modbus_server()
modbus.main()`
modbus_tcp.py
''''''
......
def _do_run(self):
"""called in a almost-for-ever loop by the server"""
#check the status of every socket
inputready = select.select(self._sockets, [], [], 1.0)[0]
#handle data on each a socket
for sock in inputready:
try:
if sock == self._sock:
# handle the server socket
client, address = self._sock.accept()
client.setblocking(0)
LOGGER.info("%s is connected with socket %d...", str(address), client.fileno())
self._sockets.append(client)
call_hooks("modbus_tcp.TcpServer.on_connect", (self, client, address))
''''''
''''''

Manipulating socketstream in Python

I'm trying to create a small, multithreaded proxyscript that allows me to proxy LDAP requests and manipulate the results (like adding extra fields, renaming them etc).
In the example below, I try to replace the field 'TEST' by 'DONE'. Is there any solution to allow this socketstream to be manipulated? Should I decode it somewhat first?
import select
import socket
import sys
import threading
import signal
import re
import random
import time
import binascii
from ldaptor.protocols import pureldap, pureber
from time import gmtime, strftime
ASTLDAP_PROXY_PORT = 1389
ASTLDAP_HOST = 'localhost'
ASTLDAP_PORT = 389
BUFFERSIZE = 1024
DELAY = 0.0001
class Forward:
def __init__(self):
self.forward = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def start(self, host, port):
try:
self.forward.connect((host, port))
return self.forward
except Exception, e:
print e
return False
class AstLdapProxyServer(threading.Thread):
input_list = []
channel = {}
def __init__(self, host, port, socket):
threading.Thread.__init__(self)
self.host = host
self.port = port
# Socket ontvangen die we meekregen bij nieuwe thread.
self.socket = socket
print "[+] New thread started for "+host+":"+str(port)
self.socket.bind((host, port))
self.socket.listen(200)
def register_signals(self):
signal.signal(signal.SIGHUP, self.signal_handler)
signal.signal(signal.SIGINT, self.signal_handler)
signal.signal(signal.SIGQUIT, self.signal_handler)
def main_loop(self):
self.input_list.append(self.socket)
while 1:
#time.sleep(DELAY)
ss = select.select
inputready, outputready, exceptready = ss(self.input_list, [], [])
for self.s in inputready:
if self.s == self.socket:
self.on_accept()
break
self.data = self.s.recv(BUFFERSIZE)
if len(self.data) == 0:
self.on_close()
else:
self.on_recv()
def on_accept(self):
forward = Forward().start(ASTLDAP_HOST, ASTLDAP_PORT)
clientsock, clientaddr = self.socket.accept()
if forward:
print clientaddr, "has connected"
self.input_list.append(clientsock)
self.input_list.append(forward)
self.channel[clientsock] = forward
self.channel[forward] = clientsock
else:
print "Can't establish connection with remote server.",
print "Closing connection with client side", clientaddr
clientsock.close()
def on_close(self):
print self.s.getpeername(), "has disconnected"
#remove objects from input_list
self.input_list.remove(self.s)
self.input_list.remove(self.channel[self.s])
out = self.channel[self.s]
# close the connection with client
self.channel[out].close() # equivalent to do self.s.close()
# close the connection with remote server
self.channel[self.s].close()
# delete both objects from channel dict
del self.channel[out]
del self.channel[self.s]
def on_recv(self):
data = self.data
# Manipulate result
output = re.sub(r'uzgEmail1', r'TEST', data)
# Send result to client (DOESN'T WORK)
self.channel[self.s].send(output)
# Send result to client (WORKS when I disable send above)
self.channel[self.s].send(data)
if __name__ == '__main__':
tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
server = AstLdapProxyServer(ASTLDAP_HOST, ASTLDAP_PROXY_PORT, tcpsock)
server.start()
try:
server.main_loop()
except KeyboardInterrupt:
sys.exit(1)

Categories