Python : threads can only be started once - python

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()

Related

ECONNABORTED when attempting to connect ESP32 and ESP8266

I'm attempting to connect an ESP32 and ESP8266 via sockets with micropython. I cannot get the ESP8266 client to connect to the ESP32 server without throwing an ECONNABORTED 103 error. Code is below, not sure what I'm doing wrong here. This seems to work when working off of my laptop and had no issues until trying to connect these two specific devies.
ESP32 Server Code:
import network
import socket
from time import sleep
SSID = 'esp'
KEY = 'meow'
ADDR = '192.168.4.1'
PORT = 2000
class socket_master:
def __init__(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.bind(('',PORT))
self.attempt = 0
def accept_connection(self):
self.sock.listen(4)
self.conn, self.addr = self.sock.accept()
def test_speed(self):
data = 'attempt ' + str(self.attempt)
self.conn.sendall(data.encode())
self.attempt += 1
attempt = 0
try:
print('starting network')
ap = network.WLAN(network.AP_IF)
print('network started')
if ap.active() == False:
ap.active(True)
sleep(1)
ap.config(essid='esp')
print(ap.config('essid'))
print('set ssid')
print(ap.ifconfig())
except:
print('failed')
sm = socket_master()
sm.accept_connection()
print('waiting for client')
while True:
sm.test_speed()
ESP8266 Client Code:
# main.py -- put your code here!
import network
import socket
SSID = 'esp'
KEY = 'meow'
ADDR = '192.168.4.1'
PORT = 2000
def do_connect():
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect('esp')
while not wlan.isconnected():
pass
print('network config:', wlan.ifconfig())
class socket_master_2:
def __init__(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((ADDR,PORT))
def receive_print(self):
data = self.sock.recv(1024)
print(data)
print(data.decode())
do_connect()
client = socket_master_2()
while True:
client.receive_print()

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 subprocess connection refused in ros melodic

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.

Python Socket Program - NameError: name 'self' is not defined. I changed the localhost, ports etc but this error refuses to go away

import socket
MAX_BUFFER_SIZE = 4096
class ClientSocket:
def __init__(self):
print("Client socket started....")
self.soc = None
def send_to_Server(self, data):
print('Time to send data to Server..... %s', data)
self.soc.send(data.encode("utf8"))
def receive_from_Server(self):
print('Time to receive from Server.....')
result_bytes = self.soc.recv(MAX_BUFFER_SIZE)
result_string = result_bytes.decode("utf8")
print("Result from server is {}".format(result_string))
def start_client(self):
self.soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.soc.connect(("localhost", 8000))
print('Client connected....')
husainshoab#hs-Len:~$ python IOTDeviceSocket.py
Traceback (most recent call last):
File "IOTDeviceSocket.py", line 7, in
class ClientSocket:
File "IOTDeviceSocket.py", line 11, in ClientSocket
self.soc = None
NameError: name 'self' is not defined
There appears to be nothing wrong with your code. I just used it to create a simple test application
# ClientSocket.py
import socket
MAX_BUFFER_SIZE = 4096
class ClientSocket:
def __init__(self):
print("Client socket started....")
self.soc = None
def send_to_Server(self, data):
print('Time to send data to Server..... %s', data)
self.soc.send(data.encode("utf8"))
def receive_from_Server(self):
print('Time to receive from Server.....')
result_bytes = self.soc.recv(MAX_BUFFER_SIZE)
result_string = result_bytes.decode("utf8")
print("Result from server is {}".format(result_string))
def start_client(self):
self.soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.soc.connect(("localhost", 8000))
print('Client connected....')
cs = ClientSocket()
cs.start_client()
cs.send_to_Server('Hello')
cs.receive_from_Server()
here's a simple test server which just spits back some JSON data
# test_server.py
import socket
from datetime import datetime
import json
def logMessage(clientMessage):
logTime = datetime.today();
msg = "{} | {}\n".format(logTime, clientMessage)
print msg
TCP_PORT = 8000
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('localhost', TCP_PORT))
# listen() puts the socket into server mode,
server.listen(1)
while True:
# wait for an incoming connection
connection, address = server.accept()
try:
# receive data in chunks of 64 bytes
while True:
data = connection.recv(64)
# how do we know if we received all the data?
if data:
# we received data from the client, log it to the file
logMessage(data)
response = {
'name' : 'Jonathan Swift',
'occupation' : 'author'
}
jsonResponse = json.dumps(response)
messageLength = len(jsonResponse)
bytesSent = 0
# send a response to the client after turning our dict into
# a JSON string
while(bytesSent < messageLength):
sent = connection.send(jsonResponse)
bytesSent += sent
else:
# no data, break out of receiving loop
break
except Exception as e:
raise
finally:
connection.close()
import socket
MAX_BUFFER_SIZE = 4096
class ClientSocket:
soc = None
def __init__(self):
print("Client socket started....")
self.soc = None
def send_to_Server(self, data):
print('Time to send data to Server..... %s', data)
self.soc.send(data.encode("utf8"))
def receive_from_Server(self):
print('Time to receive from Server.....')
result_bytes = self.soc.recv(MAX_BUFFER_SIZE)
result_string = result_bytes.decode("utf8")
print("Result from server is {}".format(result_string))
def start_client(self):
self.soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.soc.connect(("localhost", 8000))
print('Client connected....')
you should define the soc variable after class statement so that you can use it globally.

Chat with python thread. Program do not exit

I'm studying python building a chat with socket and thread. The problem is that my client does not properly exist when I execute or or type "/quit". The program ends, but the prompt does not back. I think my thread is running yet.
What I'm doing wrong?
# -*- coding: UTF-8 -*-
import socket
from threading import Thread
class Client(Thread):
def __init__(self, server_host, server_port):
Thread.__init__(self)
self.server_host = server_host
self.server_port = server_port
def run(self):
self.connect()
self.accepting = True
self.rec_message()
def connect(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((self.server_host, self.server_port))
print 'Conectado ao servidor %s:%s' % (self.server_host, self.server_port)
def close(self):
print 'Fechar'
self.sock.close()
self.accepting = False
def send_message(self, msg):
self.sock.sendall(msg)
def rec_message(self):
while self.accepting:
print self.sock.recv(1024)
# Criar objeto da classe cliente
HOST = '127.0.0.1'
PORT = 38267
client = Client(HOST, PORT)
client.start()
msg = raw_input()
while msg <> '/quit':
client.send_message(msg)
msg = raw_input()
client.close()

Categories