Python using asyncio and queue - queue

I want to use multiple workers and feeders like this:
feeder => tespPing => testSNMP => testSSH
And for the fastest result, using asyncio seems a great idea.
My current work:
# global variable
ipListPing = asyncio.Queue(30000)
ipListSNMP = asyncio.Queue(1000)
ipListSSH = []
listEquipement = EquipementList()
providerTask = None
pingsTasks = None
SNMPTasks = None
SShTasks = None
def B():
loop = asyncio.get_event_loop() # creation dune boucle asynchrone
watcherTask = asyncio.gather(*[watcher()], return_exceptions= True)
providerTask = asyncio.gather(*[provider(config['range'])], return_exceptions= True ) # generate IP
pingsTasks = asyncio.gather(*[ping() for i in range(4000)], return_exceptions= True ) # test Ping
SNMPTasks = asyncio.gather(*[SNMP() for i in range(2000)], return_exceptions= True ) # test SNMP
# SShTasks = asyncio.gather([SSH()]for i in range(2)) # currently not working next step :p
logging.debug("lancement des taches asynchrone")
all_groups = asyncio.gather(watcherTask, providerTask, pingsTasks, SNMPTasks, return_exceptions= True )
results = loop.run_until_complete(all_groups)
print('fin des taches')
# Waits until all the pending threads are done
SSH()
async def provider(range):
global ipListPing
logging.debug(f'lancement provider')
# dans un premier temps on s'occupe de diviser la plage IP (afin de reduire l'usage RAM en cas de /8 par exemple)
plageIpList = []
for iprange in range:
plageIP = IPv4Network(iprange)
if plageIP.prefixlen < 16:
plageIpList += plageIP.subnets(new_prefix=16)
continue
plageIpList.append(plageIP)
print(f"nombre de plage IP: {len(plageIpList)}")
# nous remplissons la Variable global avec un nombre d'IP "reduit"
while len(plageIpList) > 0:
iprange = plageIpList.pop()
for ip in iprange:
await ipListPing.put(ip.compressed)
logSize()
print(f'fermeture provider')
return
async def ping():
global providerTask
global ipListPing
global ipListSNMP
start = time.time()
print(f'lancement PING')
while not providerTask.done() or not ipListPing.join():
try:
ip = await ipListPing.get()
logSize()
await aioping.ping(ip)
ipListSNMP.put(ip)
except TimeoutError:
pass
finally:
ipListPing.task_done()
print('a')
end = time.time()
elapsed = end - start
print(f'Fermeture PING {elapsed}')
return True
async def SNMP():
global pingsTasks
global ipListSNMP
global ipListSSH
global listEquipement
start = time.time()
print(f'Ouverture SNMP')
while not pingsTasks.done() or not ipListPing.join():
try:
# while len(ipListSSH) > 1000:
# await asyncio.sleep(1)
ip = await ipListSNMP.get()
logSize()
if not await CPE.SNMP(ip):
ipListSSH.append(ip)
else:
listEquipement.add('ACL', ip)
except TimeoutError:
pass
finally:
ipListSNMP.task_done()
print('b')
end = time.time()
elapsed = end - start
print(f'Fermeture SNMP {elapsed} ')
return True
def SSH():
print('Debut SSH')
start = time.time()
max_threads = 100
pool = ProcessPoolExecutor(max_threads)
with ProcessPoolExecutor(max_threads) as pool:
parti = partial(CPE.SSH, username='Depfryer', password='HardPassword')
results_generator = pool.map(parti, ipListSSH)
# Results generator
for result in results_generator:
logSize()
logging.debug(result)
if(result[0]):
listEquipement.add('CPE_SSH', result[1])
else:
listEquipement.add('unknow', result[1])
end = time.time()
elapsed = end - start
return async def provider(range):
global ipListPing
logging.debug(f'lancement provider')
# dans un premier temps on s'occupe de diviser la plage IP (afin de reduire l'usage RAM en cas de /8 par exemple)
plageIpList = []
for iprange in range:
plageIP = IPv4Network(iprange)
if plageIP.prefixlen < 16:
plageIpList += plageIP.subnets(new_prefix=16)
continue
plageIpList.append(plageIP)
print(f"nombre de plage IP: {len(plageIpList)}")
# nous remplissons la Variable global avec un nombre d'IP "reduit"
while len(plageIpList) > 0:
iprange = plageIpList.pop()
for ip in iprange:
await ipListPing.put(ip.compressed)
logSize()
print(f'fermeture provider')
return
async def ping():
global providerTask
global ipListPing
global ipListSNMP
start = time.time()
print(f'lancement PING')
while not providerTask.done() or not ipListPing.join():
try:
ip = await ipListPing.get()
logSize()
await aioping.ping(ip)
ipListSNMP.put(ip)
except TimeoutError:
pass
finally:
ipListPing.task_done()
print('a')
end = time.time()
elapsed = end - start
print(f'Fermeture PING {elapsed}')
return True
# #request_concurrency_limit_decorator(4096)
async def SNMP():
global pingsTasks
global ipListSNMP
global ipListSSH
global listEquipement
start = time.time()
print(f'Ouverture SNMP')
while not pingsTasks.done() or not ipListPing.join():
try:
# while len(ipListSSH) > 1000:
# await asyncio.sleep(1)
ip = await ipListSNMP.get()
logSize()
if not await CPE.SNMP(ip):
ipListSSH.append(ip)
else:
listEquipement.add('ACL', ip)
except TimeoutError:
pass
finally:
ipListSNMP.task_done()
print('b')
end = time.time()
elapsed = end - start
print(f'Fermeture SNMP {elapsed} ')
return True
def SSH():
print('Debut SSH')
start = time.time()
max_threads = 100
pool = ProcessPoolExecutor(max_threads)
with ProcessPoolExecutor(max_threads) as pool:
parti = partial(CPE.SSH, username='Depfryer', password='HardPassword')
results_generator = pool.map(parti, ipListSSH)
# Results generator
for result in results_generator:
logSize()
logging.debug(result)
if(result[0]):
listEquipement.add('CPE_SSH', result[1])
else:
listEquipement.add('unknow', result[1])
end = time.time()
elapsed = end - start
return True
async def watcher():
global providerTask
global ipListPing
global pingsTasks
global ipListSNMP
global SNMPTasks
# await asyncio.sleep(1)
while not(SNMPTasks.done() and pingsTasks.done() and providerTask.done()):
await asyncio.sleep(0.1)
logSize()
logging.debug('watcher')
await ipListPing.join()
logging.debug('watcher')
if providerTask.done() and ipListPing.empty() is None:
logging.debug("KILL des taches de pings")
pingsTasks.cancel()
await ipListSNMP.join()
if pingsTasks.done() and ipListSNMP.empty() is None :
logging.debug("KILL des taches de SNMP")
SNMPTasks.cancel()
The current problem is that the ping task works great, but sometimes it's stuck just after and doesn't do anything else....
Someone can help?

I edited my watcher function. Now it is:
async def watcher():
global providerTask
global ipListPing
global pingsTasks
global ipListSNMP
global SNMPTasks
while True:
logSize()
await asyncio.sleep(30)
# await ipListPing.join()
if providerTask.done() and ipListPing.empty():
logging.debug("KILL des taches de pings")
pingsTasks.cancel()
if pingsTasks.done() and ipListSNMP.empty() :
logging.debug("KILL des taches de SNMP")
SNMPTasks.cancel()
return
# break
And it works great.

Related

Discord bot executes but doesn't function when testing in discord server

I've adjusted the main file and added a prefix "?" to my commands
import discord
from discord.ext import commands
import os
import asyncio
client = commands.Bot(command_prefix="?", intents = discord.Intents.all())
async def load():
for filename in os.listdir("./cogs"):
if filename.endswith(".py"):
await client.load_extension(f"cogs.{filename[:-3]}")
async def main():
async with client:
await load()
await client.start(TOKEN)
asyncio.run(main())
and added a simple ping command to test if the bot was working in discord. unfortunately all the commands except for ping does not work
import discord
from discord.ext import commands
from pymongo import MongoClient
bot_channel = BOTCHANNELID
talk_channels = [TALKCHANNELID]
level = ["test1", "test2", "test3"]
levelnum = [2,4,6]
cluster = MongoClient("MONGODBCODE")
levelling = cluster["NAME"]["NAME2"]
class levelsys(commands.Cog):
def __init__(self,client):
self.client = client
#commands.Cog.listener()
async def on_ready(self):
print("Ready!")
#commands.Cog.listener()
async def on_message(self, message):
if message.channel.id in talk_channels:
stats = levelling.find_one({"id" : message.author.id})
if not message.author.bot:
if stats is None:
newuser = {"id" : message.author.id, "xp" : 1}
levelling.insert_one(newuser)
else:
xp = stats["xp"] + 5
levelling.update_one({"id":message.author.id}, {"$set":{"xp":xp}})
lvl = 0
while True:
if xp < ((50*(lvl**2))+(50*(lvl-1))):
break
lvl += 1
xp -= ((50*((lvl-1)**2))+(50*(lvl-1)))
if xp == 0:
await message.channel.send(f"gz {message.author.mention} ! you lvled up to **level: {lvl}**")
for i in range(len(level)):
if lvl == levelnum[i]:
await message.author.add_roles(discord.utils.get(message.author.guild.roles, name=level[i]))
embed = discord.Embed(description=f"{message.author.mention} you have gotten role **{level[i]}**")
embed.set_thumbnail(url=message.author.avatar_url)
await message.channel.send(embed=embed)
#commands.command()
async def rank(self, ctx):
if ctx.channel.id == bot_channel:
stats = levelling.find_one({"id" : ctx.author.id})
if stats is None:
embed = discord.Embed(description="you haven't been studying lil bro")
await ctx.channel.send(embed=embed)
else:
xp = stats["xp"]
lvl = 0
rank = 0
while True:
if xp < ((50*(lvl**2))+(50*lvl)):
break
lvl += 1
xp -= ((50*((lvl-1)**2))+(50*(lvl-1)))
boxes = int((xp/(200*((1/2) * lvl)))*20)
rankings = levelling.find().sort("xp",-1)
for x in rankings:
rank += 1
if stats["id"] == x["id"]:
break
embed = discord.Embed(title="{}'s level stats".format(ctx.author.name))
embed.add_field(name="Name", value=ctx.author.mention, inline=True)
embed.add_field(name="XP", value=f"{xp}/{int(200*((1/2)*lvl))}", inline=True)
embed.add_field(name="Rank", value=f"{rank}/{ctx.guild.member_count}", inline=True)
embed.add_field(name="Progress Bar [lvl]", value=boxes * ":blue_square:" + (20-boxes) * ":white_large_squares:", inline = False)
embed.add_field(name='Level', value=f'{lvl}', inline=True)
embed.set_thumbnail(url=ctx.author.avatar_url)
await ctx.channel.send(embed=embed)
#commands.command()
async def dashboard(self, ctx):
if (ctx.channel.id == bot_channel):
rankings = levelling.find().sort("xp",-1)
i = 1
embed = discord.Embed(title="Rankings:")
for x in rankings:
try:
temp = ctx.guild.get_member(x["id"])
tempxp = x["xp"]
embed.add_field(name=f"{i}: {temp.name}", value=f"Total XP: {tempxp}", inline=False)
i += 1
except:
pass
if i == 11:
break
await ctx.channel.send(embed=embed)
#commands.command()
async def ping(self, ctx):
bot_latency = round(self.client.latency * 1000)
await ctx.send(f"Your ping is {bot_latency} ms !.")
async def setup(client):
await client.add_cog(levelsys(client))
I'm not too sure how I would go about fixing all the other commands to get them working. All help is much appreciated !

How a process release a redis lock which was not owned by this process?

I tried to implement a simple read-preferred read-write lock using 2 mutexes (using redis.lock.Lock), like what is described in this link (https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock)
In the [End Read] steps, I encountered this problem:
If b = 0, unlock g #(a write lock).
As, this READ process is not the one that acquired the lock, so the system throws an error. I think it has some token stored somewhere, and I can get it to use for the lock release, but I am not sure.
Could someone give me a hint? Thanks.
from enum import Enum
from redis import StrictRedis, lock
# data in Redis cache:
# "read_counter_lock_name" : 0
# "read_lock_lock_name" -> read lock, protect "read_counter_lock_name"
# "write_lock_lock_name" -> write lock, protect write data section
class Prefix(Enum):
READ = 'read_lock_'
WRITE = 'write_lock_'
READ_COUNTER = 'read_counter_'
class RedisLockParams(Enum):
TIMEOUT = 60 # maximum life for the lock in seconds = 60 seconds
SLEEP_TIME = 0.1 # the amount of time to sleep in seconds per loop iteration
# in redis lock's acquire() - sleep then retry
BLOCKING = True # acquire() should block until the lock has been acquired
BLOCKING_TIMEOUT = None # maximum amount of time in seconds to spend trying
# to acquire the lock
class ReadWriteLock:
def __init__(self, lock_name: str, redis_host: str, redis_port: int, redis_key: str):
self.__read_lock_name = Prefix.READ.value + lock_name
self.__write_lock_name = Prefix.WRITE.value + lock_name
self.__read_counter_key = Prefix.READ_COUNTER.value + lock_name
# self.__redis_host = redis_host
# self.__redis_port = redis_port
# self.__redis_key = redis_key
self.__cache = StrictRedis(host = redis_host,
port = redis_port,
db=0, # up to 16 logical database
password = redis_key,
ssl=True)
print(f'ping return:{self.__cache.ping()}')
# set the read counter to 0, if it does not exist.
self.__cache.setnx(self.__read_counter_key, 0)
# init the read lock
self.__read_lock = lock.Lock(self.__cache,
self.__read_lock_name,
RedisLockParams.TIMEOUT.value,
RedisLockParams.SLEEP_TIME.value,
RedisLockParams.BLOCKING.value,
RedisLockParams.BLOCKING_TIMEOUT.value)
# init the write lock
self.__write_lock = lock.Lock(self.__cache,
self.__write_lock_name,
RedisLockParams.TIMEOUT.value,
RedisLockParams.SLEEP_TIME.value,
RedisLockParams.BLOCKING.value,
RedisLockParams.BLOCKING_TIMEOUT.value)
def acquire_read_lock(self) -> bool:
write_lock_acquired = False
self.__read_lock.acquire()
read_counter = self.__cache.incr(self.__read_counter_key)
if (read_counter == 1):
write_lock_acquired = self.__write_lock.acquire() # acquire write lock
self.__read_lock.release()
return write_lock_acquired
def release_read_lock(self):
read_lock_acquired = self.__read_lock.acquire()
read_counter = self.__cache.decr(self.__read_counter_key)
if read_counter == 0 and read_lock_acquired:
self.__write_lock.release() # release the write lock-> issue!!!
self.__read_lock.release()
def acquire_write_lock(self) -> bool:
return self.__write_lock.acquire()
def release_write_lock(self):
self.__write_lock.release()
I am having the same issue.
"LockNotOwnedError("Cannot release a lock"\nredis.exceptions.LockNotOwnedError: Cannot release a lock that's no longer owned"
redis = Redis.from_url(redis_url)
try:
with redis.lock(name, timeout=timeout, blocking_timeout=blocking_timeout) as redis_lock:
yield redis_lock
except RedisLockError as e:
logger.warning("Cannot acquire lock", name=name, timeout=timeout, blocking_timeout=blocking_timeout)
raise LockError(f"Cannot acquire lock {name}") from e
Can someone add some hints?
I have figured out how to release the not-owned redis lock by taking a look at the redis' python library source code. Below is the modified version of the multiread-single-write lock class.
# read_write_lock.py
from enum import Enum
from redis import StrictRedis, lock
# data in Redis cache:
# "read_counter_lock_name" : 0
# "read_lock_lock_name" -> read lock, protect "read_counter_lock_name"
# "write_lock_lock_name" -> write lock, protect write data section
class Prefix(Enum):
READ = 'read_lock_'
WRITE = 'write_lock_'
READ_COUNTER = 'read_counter_'
class RedisLockParams(Enum):
TIMEOUT = 60 # maximum life for the lock in seconds = 60 seconds
SLEEP_TIME = 0.1 # the amount of time to sleep in seconds per loop iteration
# in redis lock's acquire() - sleep then retry
BLOCKING = True # acquire() should block until the lock has been acquired
BLOCKING_TIMEOUT = None # maximum amount of time in seconds to spend trying
# to acquire the lock
class ReadWriteLock:
def __init__(self, lock_name: str, redis_host: str, redis_port: int, redis_key: str):
self.__read_lock_name = Prefix.READ.value + lock_name
self.__write_lock_name = Prefix.WRITE.value + lock_name
self.__read_counter_key = Prefix.READ_COUNTER.value + lock_name
self.__cache = StrictRedis(host = redis_host,
port = redis_port,
db=0, # up to 16 logical database
password = redis_key,
ssl=True)
# set the read counter to 0, if it does not exist.
self.__cache.setnx(self.__read_counter_key, 0)
# init the read lock
self.__read_lock = lock.Lock(self.__cache,
self.__read_lock_name,
RedisLockParams.TIMEOUT.value,
RedisLockParams.SLEEP_TIME.value,
RedisLockParams.BLOCKING.value,
RedisLockParams.BLOCKING_TIMEOUT.value)
# init the write lock
self.__write_lock = lock.Lock(self.__cache,
self.__write_lock_name,
RedisLockParams.TIMEOUT.value,
RedisLockParams.SLEEP_TIME.value,
RedisLockParams.BLOCKING.value,
RedisLockParams.BLOCKING_TIMEOUT.value)
def acquire_read_lock(self) -> bool:
write_lock_acquired = False
self.__read_lock.acquire()
read_counter = self.__cache.incr(self.__read_counter_key)
if (read_counter == 1):
write_lock_acquired = self.__write_lock.acquire() # acquire write lock
self.__read_lock.release()
return write_lock_acquired
def release_read_lock(self):
read_lock_acquired = self.__read_lock.acquire()
if read_lock_acquired:
read_counter = self.__cache.decr(self.__read_counter_key)
if read_counter == 0:
if self.__write_lock.owned():
self.__write_lock.release()
else: # if the lock was not owned, just take its token and override
write_lock_token = self.__cache.get(self.__write_lock_name)
self.__write_lock.local.token = write_lock_token
self.__write_lock.release()
self.__read_lock.release()
def acquire_write_lock(self) -> bool:
return self.__write_lock.acquire()
def release_write_lock(self) -> None:
self.__write_lock.release()

Python code after sockets connection executed only once

What are the intentions of this program:
I want to send some commands from a client to a server using sockets, the server then send these command to an Arduino using serial. And another thing that I want the server to do in the future is that periodically sends other commands to the Arduino without getting any input from the client, so the sockets needs to be non-blocking or there needs to be another way to run the code separately from the sockets code.
The problem is that the part that is supposed to send the command to the Arduino only runs once.
What I have come up with after playing with the debugger in Pycharm, is that the problem is that the following line blocks after a connection has been established, and thus not allowing the rest of the code to be run.
conn, addr = s.accept()
Is this correct, or is there something else wrong?
I have tried to set the socket to non-blocking but when I do this I get an error.
"BlockingIOError: [WinError 10035] A non-blocking socket operation could not be completed immediately"
I have some basic knowledge of C/C++ and C# and am new to Python.
server.py
import socket
import serial
import sys
from _thread import *
import threading
import queue
# command that the client sends are "ON" and "OFF"
class serialConnect:
comPort =' '
baudrate = 115200
myserial = serial.Serial('COM5', baudrate)
def serialstart(self):
# self.comPort = input('Comport: ')
try:
self.myserial.open()
except IOError:
print('Port is already open!')
def serialRead(self):
data = self.myserial.read(16)
data.decode('UTF-8')
return data
def serialWrite(self, data):
data += '\n' #the arduino needs a \n after each command.
databytes = data.encode('UTF-8')
self.myserial.write(databytes)
print('send data: ', databytes)
def threaded_client(conn, dataqueue):
data = {bytes}
conn.send(str.encode('welcome, type your info \n'))
while True:
data = conn.recv(2048)
if not data:
break
reply = 'server output: ' + data.decode('UTF-8')
dataqueue.put(data.decode('UTF-8'))
print("Items in queue: ",dataqueue.qsize())
#conn.sendall(str.encode(reply))
print("Recieved data in threaded_client: ", data.decode('UTF-8') + '\n')
conn.close()
def Main():
ser = serialConnect()
host = ''
port = 5555
dataRecieved = 'hello'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
s.setblocking(1) #when set to non-blocking error occurs : "BlockingIOError: [WinError 10035] A non-blocking socket operation could not be completed immediately"
workQueue = queue.Queue(10)
try:
s.bind((host,port))
except socket.error as e:
print(str(e))
s.listen(5)
print('waiting for a connection')
while True:
try:
conn, addr = s.accept() #once connection is established it blocks?
print('connected to: ' + addr[0] + ':' + str())
t = threading.Thread(target=threaded_client, args=(conn, workQueue))
t.daemon = True
t.start()
except:
e = sys.exc_info()
print('Error:', e)
# This section of code is only run once, doesn't matter if put inside try block or not. :(
dataRecieved = workQueue.get()
print('The recieved data: ', dataRecieved)
ser.serialstart()
ser.serialWrite(dataRecieved)
if __name__ == '__main__':
Main()
client.py
import socket
def Main():
host = '127.0.0.1'
port = 5555
message = "<,R,G,B,>"
mySocket = socket.socket()
mySocket.connect((host, port))
while message != 'q':
message = input(" -> ")
mySocket.send(message.encode())
mySocket.close()
if __name__ == '__main__':
Main()
Arduino Code
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
int LEDpin = 10;
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin 13 as an output.
pinMode(10, OUTPUT);
Serial.begin(19200);
}
// the loop function runs over and over again forever
void loop() {
serialEvent();
if(stringComplete){
Serial.println(inputString);
if(inputString == "ON\n"){
digitalWrite(LEDpin, HIGH); // turn the LED on (HIGH is the voltage level)
}
if(inputString == "OFF\n"){
digitalWrite(LEDpin, LOW); // turn the LED off by making the voltage LOW
}
inputString = "";
stringComplete = false;
}
}
void serialEvent()
{
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}
Refactored server code for anyone that is interested in it.
I am not sure if this is up to standard, but it is working.
import serial
import socket
import queue
import sys
import threading
class serialConnect:
comPort = 'COM5'
baudrate = 115200
myserial = serial.Serial(comPort, baudrate)
def serial_run(self):
# self.comPort = input('Comport: ')
try:
if not self.myserial.isOpen():
self.myserial.open()
else:
print('Port is already open!')
except IOError as e:
print('Error: ', e)
def serial_read(self):
data = self.myserial.read(16)
data.decode('UTF-8')
return data
def serial_write(self, data):
data += '\n' #the arduino needs a \n after each command.
databytes = data.encode('UTF-8')
self.myserial.write(databytes)
print('send data: ', databytes)
class socketServer:
host = ''
port = 5555
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.setblocking(1)
data_queue = queue.Queue(1)
def __init__(self):
try:
self.soc.bind((self.host, self.port))
except:
print('Bind error: ', sys.exc_info())
self.soc.listen(5)
def socket_accept_thread(self):
while True:
try:
print('Waiting for a new connection')
conn, addr = self.soc.accept()
client_thread = threading.Thread(target=self.threaded_client, args=(conn, self.data_queue))
client_thread.daemon = True
client_thread.start()
except:
print('Accept thread Error: ', sys.exc_info())
def threaded_client(self, conn, data_queue):
# conn.send(str.encode('welcome, type your info \n'))
try:
while True:
data = conn.recv(2048)
if not data:
break
# reply = 'server output: ' + data.decode('UTF-8')
data_queue.put(data.decode('UTF-8'))
print("Items in queue: ", data_queue.qsize())
# conn.sendall(str.encode(reply))
print("Received data in threaded_client: ", data.decode('UTF-8'))
except:
print("Error: ", sys.exc_info())
conn.close()
def get_data(self):
data = self.data_queue.get()
return data
def Main():
server = socketServer()
arduino_conn = serialConnect()
accept_thread = threading.Thread(target=server.socket_accept_thread)
data_received = 'Nothing received'
while True:
if not accept_thread.is_alive():
accept_thread.daemon = True
accept_thread.start()
arduino_conn.serial_run()
data_received = server.get_data()
arduino_conn.serial_write(data_received)
if __name__ == '__main__':
Main()

server doesn't send data to clients

I have this piece of code for server to handle clients. it properly receive data but when i want to send received data to clients nothing happens.
server
import socket
from _thread import *
class GameServer:
def __init__(self):
# Game parameters
board = [None] * 9
turn = 1
# TCP parameters specifying
self.tcp_ip = socket.gethostname()
self.tcp_port = 9999
self.buffer_size = 2048
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.s.bind((self.tcp_ip, self.tcp_port))
except:
print("socket error, Please try again! ")
self.s.listen(5)
print('Waiting for a connection...')
def messaging(self, conn):
while True:
data = conn.recv(self.buffer_size)
if not data:
break
print("This data from client:", data)
conn.send(data)
def thread_run(self):
while True:
conn, addr = self.s.accept()
print('connected to: ' + addr[0] + " : " + str(addr[1]))
start_new_thread(self.messaging, (conn,))
def main():
gameserver = GameServer()
gameserver.thread_run()
if __name__ == '__main__':
main()
'
I want to if data received completely send to clients by retrieve the address of sender and send it to other clients by means of conn.send() but seems there is no way to do this with 'send()' method.
The piece of client side code
'
def receive_parser(self):
global turn
rcv_data = self.s.recv(4096)
rcv_data.decode()
if rcv_data[:2] == 'c2':
message = rcv_data[2:]
if message[:3] == 'trn':
temp = message[3]
if temp == 2:
turn = -1
elif temp ==1:
turn = 1
elif message[:3] == 'num':
self.set_text(message[3])
elif message[:3] == 'txt':
self.plainTextEdit_4.appendPlainText('client1: ' + message[3:])
else:
print(rcv_data)
'
the receiver method does not receive any data.
I modified your code a little(as I have python 2.7) and conn.send() seems to work fine. You can also try conn.sendall(). Here is the code I ran:
Server code:
import socket
from thread import *
class GameServer:
def __init__(self):
# Game parameters
board = [None] * 9
turn = 1
# TCP parameters specifying
self.tcp_ip = "127.0.0.1"#socket.gethostname()
self.tcp_port = 9999
self.buffer_size = 2048
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.s.bind((self.tcp_ip, self.tcp_port))
except:
print("socket error, Please try again! ")
self.s.listen(5)
print('Waiting for a connection...')
def messaging(self, conn):
while True:
data = conn.recv(self.buffer_size)
if not data:
break
print("This data from client:", data)
conn.send(data)
def thread_run(self):
while True:
conn, addr = self.s.accept()
print('connected to: ' + addr[0] + " : " + str(addr[1]))
start_new_thread(self.messaging, (conn,))
def main():
gameserver = GameServer()
gameserver.thread_run()
main()
Client code:
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1", 9999))
def receive_parser():
#global turn
s.sendall("hello world")
rcv_data = s.recv(4096)
# rcv_data.decode()
# if rcv_data[:2] == 'c2':
# message = rcv_data[2:]
# if message[:3] == 'trn':
# temp = message[3]
# if temp == 2:
# turn = -1
# elif temp ==1:
# turn = 1
# elif message[:3] == 'num':
# self.set_text(message[3])
# elif message[:3] == 'txt':
# self.plainTextEdit_4.appendPlainText('client1: ' + message[3:])
# else:
print(rcv_data)
receive_parser()

NameError: global name 'Carnage' is not defined

I know it was asked a million times before, but I need a little help getting this working, as the code is not mine.
so like that i update a code hope it will make some undarstands of it
# coding=utf-8
import urllib, re, sys, threading, cookielib, urllib2
from BeautifulSoup import BeautifulSoup
### Головная функция
def main():
agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)'
aCarnage = Carnage('YourNick', 'YourPass', 'arkaim.carnage.ru', 'cp1251', agent)
aCarnage.login()
me = aCarnage.inf(aCarnage.user)
# Если ранен - выйти
if me['inj']:
aCarnage.logout()
exit(1)
aCarnage.urlopen('main.pl')
# Подождать пока здоровье восстановится
while(me['hp_wait']):
time.sleep(me['hp_wait'])
me = aCarnage.inf(aCarnage.user)
# Найти подходящую заявку
aCarnage.find()
me = aCarnage.inf(aCarnage.user)
# Если заявка состоялась - в бой!
if me['battle']: aCarnage.fight()
# После боя - выход из игры
aCarnage.logout()
class Opener:
def __init__(self, host, encoding, agent):
self.host = host
self.encoding = encoding
self.agent = agent
self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookielib.CookieJar()))
def urlopen(self, goto, data = None):
f = self.opener.open(urllib2.Request(
"http://%s/%s" % (self.host, goto),
self.urlencode(data),
{"User-agent" : self.agent}
))
result = f.read()
self.soup = BeautifulSoup(result)
def urlencode(self, data):
if data is None: return None
for key in data:
data[key] = data[key].encode(self.encoding, 'ignore')
return urllib.urlencode(data)
class CarnageBot(Opener):
### Конструктор принимает логин, пароль, кодировку (cp1251) и идентификатор браузера
def __init__(self, user, password, host, encoding, agent):
self.user = user
self.password = password
Opener.__init__(self, host, encoding, agent)
### Получить информацию об игроке - например о самом себе
def inf(self, user):
self.urlopen('inf.pl?' + self.urlencode({'user': user}))
# Кол-во жизни
onmouseover = self.soup.find('img', onmouseover = re.compile(unicode('Уровень жизни:', 'utf8')))
m = re.search('([0-9]+).([0-9]+)', onmouseover['onmouseover'])
hp = int(m.group(1))
hp_max = int(m.group(2))
hp_wait = (100 - (hp * 100) / hp_max) * 18
# Уровень
td = self.soup.find('td', text = re.compile(unicode('Уровень:', 'utf8')))
level = int(td.next.string)
# Ранен или нет
inj = 0
if self.soup.find(src = re.compile(unicode('travma.gif', 'utf8'))): inj = 1
# В бою или нет
battle = 0
if self.soup.find(text = re.compile(unicode('Персонаж находится в бою', 'utf8'))): battle = 1
hero = {'level': level, 'hp': hp, 'hp_max': hp_max, 'hp_wait': hp_wait, 'inj': inj, 'battle': battle}
return hero
### Войти в игру
def login(self):
data = {'action': 'enter', 'user_carnage': self.user, 'pass_carnage': self.password}
self.urlopen('enter.pl', data)
self.urlopen('main.pl')
### Выйти из игры
def logout(self):
self.urlopen('main.pl?action=exit')
### В бой!!!
def fight(self):
self.urlopen('battle.pl')
while True:
# Добить по таймауту
if self.soup.find(text = re.compile(unicode('Противник потерял сознание', 'utf8'))):
self.urlopen('battle.pl?cmd=timeout&status=win')
break
if self.soup.find(text = re.compile(unicode('Бой закончен.', 'utf8'))):
break
reg = re.compile(unicode('Для вас бой закончен. Ждите окончания боя.', 'utf8'))
if self.soup.find(text = reg):
break
cmd = self.soup.find('input', {'name' : 'cmd', 'type' : 'hidden'})
to = self.soup.find('input', {'name' : 'to', 'type' : 'hidden'})
# Есть ли по кому бить?!
if cmd and to:
a = random.randint(1, 4)
b0 = random.randint(1, 4)
b1 = random.randint(1, 4)
while b1 == b0: b1 = random.randint(1, 4)
pos = 2
arg = (cmd['value'], to['value'], pos, a, a, b0, b0, b1, b1)
self.urlopen('battle.pl?cmd=%s&to=%s&pos=%s&A%s=%s&D%s=%s&D%s=%s' % arg)
else:
self.urlopen('battle.pl')
time.sleep(random.randint(5, 30))
### Найти заявку - подающий заявку должен быть на 1 уровень ниже нашего
def find(self):
me = self.inf(self.user)
while True:
v = ''
self.urlopen('zayavka.pl?cmd=haot.show')
reg = re.compile(unicode('Текущие заявки на бой', 'utf8'))
script = self.soup.find('fieldset', text = reg).findNext('script')
m = re.findall('.*', script.string)
for value in m:
if value.find('group.gif') < 0: continue
if value.find('(%i-%i)' % (me['level'] - 2, me['level'])) < 0: continue
t = re.search(',([0-9]{1,2}),u', value)
if not t: continue
t = int(t.group(1))
v = re.search('tr\(([0-9]+)', value).group(1)
print 'Found battle t=%i v=%s' % (t, v)
break
if v: break
time.sleep(80)
nd = self.soup.find('input', {'name' : 'nd', 'type' : 'hidden'})
self.urlopen('zayavka.pl?cmd=haot.accept&nd=%s&battle_id=%s' % (nd['value'], v))
time.sleep(t + 30)
if __name__ == '__main__': main()
The error is:
NameError: global name 'Carnage' is not defined
The cause of your error is that Carnage has not been defined. Maybe you forgot to import a library which provides Carnage?
Also, your code as posted is incorrectly indented, which is a syntax error.
Update: Apparently you took this code from http://github.com/Ejz/Common/tree/master/carnage-bot . Reading that source, it looks like the line
aCarnage = Carnage('YourNick', 'YourPass', 'arkaim.carnage.ru', 'cp1251', agent)
Should be
aCarnage = CarnageBot('YourNick', 'YourPass', 'arkaim.carnage.ru', 'cp1251', agent)
Because the methods called on aCarnage are defined further down the file for class CarnageBot.