I have a zynq core board with its own processor , the zynq has hardcoded testfunctions which upon receiving the associated command for a function returns the data requested for example command 200 returns temperature sensor data . Using UDP in python I want to send commands to the zynq board.
Also the function will be called only upon defining the function parameters , MessageID is the command to be excuted , UniqueId and Overload is just a random number and Subgroup and SensorIndex are the inbuilt or fixed ids in the zyng for example group 0 and index 1 , this functions I have defined in another script called testfunctions def systemMonitorGetSensor(MessageID, UniqueID, Overload, Subgroup, SensorIndex):
import socket
import os
import testfunctions as test
def main(self):
def openconnection():
UDP_IP = "172.29.11.113" # Get local machine name
UDP_PORT = 4711 # Reserve a port for your service
MESSAGE = b"Hello SCE100...python talking"
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
def ping():
UDP_IP = "172.29.11.113"
response = os.system('ping -c 1 ' + UDP_IP)
if response == 0:
print(UDP_IP, 'is up')
else:
print(UDP_IP, 'is down')
def stopsocket(self):
self.sock.shutdown(socket.SOCK_DGRAM)
self.sock.closes()
openconnection()
ping()
MessageID = int(input("Enter the TaskID to be executed : "))
print(MessageID)
main ( MessageID )
if MessageID == 200:
test.systemMonitorGetAllSensors(200,0,0)
if MessageID == 201:
systemMonitorResponce()
Related
I'm building a chat server for a school project, but when I ran the code I got this error:
TypeError: bind(): AF_INET address must be tuple, not str
import socket
import select
#server booting up with ip + port (server.bind) and listnes for new connections (server.listen) and printing in the and booting up to let the user know
server = socket.socket()
server.bind(("192.168.1.14, 4434"))
server.listen(5)
inputs = [server]
print("booting up the server...")
#notify for new connections
def notify_all(msg, non_receptors):
for connection in inputs:
if connection not in non_receptors:
connection.send(msg)
#function that check for new connections and greets the new users + updating the amount of people connected to the server
def greet(client):
names = [n.getpeername() for n in inputs if n is not client and n is not server]
greetMsg = "hello user! \n users online:" + str(names)
client.send(greetMsg.encode())
while inputs:
readables, _, _ = select.select(inputs, [], [])
for i in readables:
if i is server:
client, address = server.accept()
inputs.append(client)
print("connected to new client")
greet(client)
notify_all(f"client {address} enterd".encode(), [server, client])
else:
try:
data = i.recv(1024)
notify_all(str(str(i.getpeername()) + ">>>" + data.decode()).encode(), [server, i])
except Exception as e:
print(e)
inputs.remove(i)
print(f"client {i.getpeername()} BYE")
("192.168.1.14, 4434") is exactly the same as "192.168.1.14, 4434" (without parentheses), which is a string. As the error message says, the argument to bind should be a tuple, not a string:
server.bind(("192.168.1.14", 4434))
The problem line is: server.bind(("192.168.1.14, 4434")).
You pass it a single string of "192.168.1.14, 4434" instead of a tuple that contains two separate values.
You need to change it to: server.bind(("192.168.1.14", 4434))
Note that the port should be int, not str.
This works :
while True:
print('')
command_input = input()
if command_input == 'q':
break
mcp = Mqtt_command_publisher
mcp.publish_command(device_ids, command_input)
But this does not:
class Mqtt_command_bl:
def update_minutes_to_run_at(json):
if not json['device_ids']:
return 'Request must contain device ids'
device_ids = json['device_ids']
minutes_to_run_at = json['minutes_to_run_at']
minutes_to_run_at_command_section = ''
for i in minutes_to_run_at:
m = '"{}",'.format(i)
if i == minutes_to_run_at[len(minutes_to_run_at) - 1]:
m = '"{}"'.format(i)
minutes_to_run_at_command_section += m
#command_input = 'jq \'.+{{minutes_to_run_at:[{}]}}\' /home/pi/hallmonitor_lite/config.json > /home/pi/hallmonitor_lite/tmp.json && mv /home/pi/hallmonitor_lite/tmp.json /home/pi/hallmonitor_lite/new_config.json'.format(minutes_to_run_at_command_section)
command_input = 'mkdir /home/pi/hallmonitor_lite/hello_world'
mcp = Mqtt_command_publisher
mcp.publish_command(device_ids, command_input)
return 'Success'
The class they both call:
class Mqtt_command_publisher:
def publish_command(device_ids, command_input):
mqtt_msg = json.dumps({'device_ids':device_ids,'command':command_input})
print('\n{}'.format(mqtt_msg))
client = mqtt.Client()
client.connect('********', ****, 30)
client.publish('topic/commands', mqtt_msg)
client.disconnect()
Looking at the print statements output from the Mqtt_command_publisher, the output can be the exact same, however, only one of them will execute, and I don't see why one works and the other does not.
I tried this command for testing: mkdir /home/pi/hallmonitor_lite/hello_world
This is the receiving part:
device_id = 0
with open('/home/pi/hallmonitor_lite/config.json') as json_data_file:
data = json.load(json_data_file)
device_id = data['device_id']
def on_connect(client, userdata, flags, rc):
print("Connected with result code: " + str(rc))
client.subscribe("topic/commands")
def on_message(client, userdata, msg):
mqtt_message = msg.payload.decode()
print(mqtt_message)
ids_and_command = json.loads(mqtt_message)
if str(device_id) in ids_and_command['device_ids'] or not ids_and_command['device_ids']:
print(('Executing: {}').format(ids_and_command['command']))
os.system(ids_and_command['command'])
client = mqtt.Client()
client.connect("********", ****, 30)
client.on_connect = on_connect
client.on_message = on_message
client.loop_forever()
Any ideas?
The problem is most likely because the second set of code is creating a message bigger than will fit in a single TCP packet.
This is a problem because you are not running the client network loop so the client.publish command can only send a single packet, the rest of the message would have been sent by the network loop, but even if it was running you are calling disconnect immediately after the publish call.
The client is not meant to be spun up for a single message like that, it is meant to be started and then left running with you just calling the publish method when you want to send a message. If you don't want to do that or can't for some reason there is a specific helper class in the paho python package that will do all the heavy lifting of starting the client, sending the message and then tearing everything down nicely. The docs for the single publish are here.
import paho.mqtt.publish as publish
publish.single("paho/test/single", "payload", hostname="mqtt.eclipse.org")
For part 1 of the project, you will implement a simple go-back-N protocol similar to TCP. This protocol is called the 352RDPv1.
(unfortunately my python knowledge is not that strong, I am being forced to code it in python)
I must implement: init(udp_port1, udpport2)
socket()
connect(address)
I am given the following pseudo code:
import binascii
import socket as syssock
import struct
import sys
# this init function is global to the class and
# defines the UDP ports all messages are sent
# and received from.
def init(UDPportTx,UDPportRx): # initialize your UDP socket here
# create a UDP/datagram socket
# bind the port to the Rx (receive) port number
pass
class socket:
def __init__(self): # fill in your code here
# create any lists/arrays/hashes you need
return
def connect(self,address): # fill in your code here
global UDPportTx # example using a variable global to the Python module
# create a new sequence number
# create a new packet header with the SYN bit set in the flags (use the Struct.pack method)
# also set the other fields (e.g sequence #)
# add the packet to the outbound queue
# set the timeout
# wait for the return SYN
# if there was a timeout, retransmit the SYN packet
# set the outbound and inbound sequence numbers
return
I have given a shot so far at a few methods but I know I have errors and my program does not work.
import binascii
import socket as syssock
import struct
from collections import namedtuple
import sys
import select
version = 0x1
header_len = 7
payload_len = 0
flags = 0
SOCK352_SYN = 0x01
SOCK352_FIN = 0x02
SOCK352_ACK = 0x04
SOCK352_RESET = 0x08
SOCK352_HAS_OPT = 0xA0
sequence_no = 0
ack_no = 0
timeout = 0.2
#given these values to set them to
def init(UDPportTx,UDPportRx):
global sock
global useRx
global useTx
useTx = int(UDPportTx)
useRx = int(UDPportRx)
sock = syssock.syssock(syssock.AF_INET, syssock.SOCK_DGRAM)
sock.bind(('', useRx))
print "Listening on port :", useRx
pass
class socket:
def __init__(self):
global pkt
pkt = namedtuple("pkt",["version", "flags", "sequence_no", "ack_no", "payload_len"])
return
def connect(self, address):
global header_raw
udpPkt = struct.Struct('!BLBBB')
header_raw = udpPkt.pack(version, SOCK352_SYN, sequence_no, ack_no, payload_len)
sock.sendto(header_raw, ('', useTx))
return
I believe I am having errors in these first few methods and before I move onto the others I need to figure in I want to see if anyone is able to help me understand how to handle these few to begin.
Edit
Worked around this problem by switching to UDP. See that updated code snippets after the break.
I'm having trouble with my threaded tcp server in python. The goal is to establish a communication link between Matlab and a Python server to allow for querying a database. This example only works properly once, then I have to restart Matlab to get the message echoed back again.
The Python side:
import SocketServer
from threading import Thread
class service(SocketServer.BaseRequestHandler):
def handle(self):
self.data = 'dummy'
print "Client connected with ", self.client_address
while len(self.data):
self.data = self.request.recv(1024).strip()
print self.data
self.request.sendall(self.data.upper())
print "Client exited"
self.request.close()
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
t = ThreadedTCPServer(('',1522), service)
t.serve_forever()
And the Matlab Code:
t = ThreadedTCPServer(('',1522), service)
t.serve_forever()
t = tcpip('localhost', 1522);
fopen(t);
% write a message
fwrite(t, 'This is a test message.');
% read the echo
bytes = fread(t, [1, t.BytesAvailable]);
char(bytes)
% close the connection
fclose(t);
So, while i'm expecting the data to get echoed back, this only occurs on the first run, i.e. right after I've started Matlab. If I run it again, I get the message on the python side, but it is not echoed again. Ideas?
The Updated Python Code:
x = np.array([[55, 1000, 45], [20, 3, 10]])
class UDP_Interrupt(SocketServer.BaseRequestHandler):
def setup(self):
pass
def handle(self):
data = self.request[0].strip()
print data
socket = self.request[1]
print "{}{} wrote:".format(self.client_address[0], self.client_address)
print data
print x
socket.sendto(x.tostring('C'), self.client_address)
#scipy.io.savemat('/Users/empire/Documents/MATLAB/hybridQuadSim/quaternionController/models/mapData.mat', mdict={'mapData': x})
def finish(self):
pass
class ThreadedUDPServer(SocketServer.ThreadingMixIn, SocketServer.UDPServer):
pass
if __name__ == "__main__":
map_server = ThreadedUDPServer((HOST, PORT), UDP_Interrupt)
# terminate with Ctrl-C
try:
server_thread = Thread(target=map_server.serve_forever)
server_thread.daemon = False
server_thread.start()
print "Server loop running in thread:", server_thread.name
except KeyboardInterrupt:
sys.exit(0)
And for Matlab:
% connect to the server
t = udp('localhost', 2002);
fopen(t);
% write a message
fwrite(t, 'This is a test message.');
% read the echo
bytes = fread(t, [t.BytesAvailable, 1], 'char');
temp = reshape(bytes, [8 6]);
z = [0,0,0,0,0,0]
for col = 1:6
bytepack=uint64(0);
for row = 1:8
temp(9-row, col)
bytepack = bitshift(temp(9 - row, col),8*(8-row));
z(col) = bitor(bytepack,z(col));
temp(row, col);
end;
end;
% close the connection
fclose(t);
This setup seems to work well enough, but would appreciate any feedback or corrections offered. I would like a more robust solution to the problem of reconstructing the numpy array into a matrix in Matlab.
I need to built a python chat and I'm stacked in the very final step. I've built the server and the client and I have the following problem while running the code:
server.py 127.0.0.1
-in a separate window client.py 127.0.0.1
-another client
-type the nicknames to chat for both clients and get the correct answer 'yuppie' meaning you are connected
a client try to speak
message is not read by the other client until it doesn't print something, after printing it get the message printed on its screen correctly.
I'd like to get the message without being obliged to print something, it's pretty unrealistic!!! Code of client and server are below in 2 different classes. Thank you!
#! /usr/bin/env python
import socket,sys,select,re
PORT=1060
class Server():
def __init__(self,host):
#building listen_sock
self.listen_sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.listen_sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
self.listen_sock.bind((host,PORT))
self.listen_sock.listen(20)
#building dict for socket and socket state
self.sockets={self.listen_sock.fileno(): self.listen_sock}
self.socket_state={self.listen_sock.fileno():''}
#building poll object
self.poll=select.poll()
self.poll.register(self.listen_sock,select.POLLIN)
#users' list
self.users_list={}
#DON'T LOOK HERE
#initialize the sender
#self.sender=0
# self.users=re.compile("\s*\$(get users connected)$\s*",re.IGNORECASE)
# self.nick=re.compile("\s*\$\$(\w*\d*)\$\$\s*",re.IGNORECASE)
# self.quit=re.compile("\s*\$(quit)\$\s*",re.IGNORECASE)
#self.commands=[self.users,self.nick,self.quit]
#funcion to receive message from client (work well)
def recv_until(self,fd,suffix):
self.message=''
#checking the end of the message
while not self.message.endswith(suffix):
data=self.sockets[fd].recv(16)
if not data:
raise EOFError('socket closed before we saw %r' % suffix)
self.message+=data
self.message=self.message[:-1]
#delete client (work well)
def del_client(self,fd):
del self.users_list[fd]
del self.socket_state[fd]
self.poll.unregister(fd)
#print the remaining active connections
if not len(self.users_list):
print 'Anyone is connected, waiting for new connection'
else:
print self.users_list
#add new client and change the of the file descriptor for that client (work well)
def new_client(self,fd):
newsock, sockname = self.listen_sock.accept()
print 'new connection from ', newsock.getpeername()
newsock.setblocking(False)
#recording the new connection
fd=newsock.fileno()
self.sockets[fd]=newsock
self.poll.register(fd,select.POLLOUT)
self.socket_state[fd]='ask nick'
#DON'T LOOK HERE
# def handle_query(self,fd):
# for n,command in enumerate(self.commands):
# match=command.search(self.message)
# if n==1 and match:
# self.users_list[self.sockets[fd].getpeername()]=match.group(1)
# print self.users_list
# for value in self.users_list.values():
# self.sockets[fd].sendall(value+'\n')
#starting the main function of the class
def chat(self):
while True:
#here il where the code hangs up waitng and waiting (WORKS BAD)
#return a tuple, identify where (fd) the event (event) is happening
for fd,event in self.poll.poll():
#print the state of each socket and the poll object
print self.socket_state
print self.poll.poll()
#starting the state machine
#remove closed sockets
if event & (select.POLLHUP | select.POLLERR |
select.POLLNVAL):
#deleting the socket closed at fd
self.del_client(fd)
#if the socket referred to is our listen_sock and we have a new connection request
elif self.sockets[fd] is self.listen_sock:
#recording the new entry!
self.new_client(fd)
#managing all the situation where it is necessary to answer to a client
#and changing the state of the socket and that of the sockets[fd]
elif event & select.POLLOUT:
if self.socket_state[fd]=='ask nick':
self.sockets[fd].sendall('identify\n')
self.poll.modify(self.sockets[fd],select.POLLIN)
self.socket_state[fd]='get user'
if self.socket_state[fd]=='invalid nick':
self.sockets[fd].sendall('invalid nick\n')
for value in self.users_list.values():
self.sockets[fd].sendall('\n'+value+'\n')
self.socket_state[fd]='ask nick'
if self.socket_state[fd]=='connected':
print '3'
self.sockets[fd].sendall('yuppie\n')
self.poll.modify(self.sockets[fd],select.POLLIN)
self.socket_state[fd]='ready to communicate'
if self.socket_state[fd]=='ready to receive':
self.sockets[fd].sendall(self.message)
print '4'
self.poll.modify(self.sockets[fd],select.POLLIN)
self.socket_state[fd]='ready to communicate'
#managing all the situation where it is necessary to get values from clients
elif event & select.POLLIN:
if self.socket_state[fd]=='get user':
self.recv_until(fd,'\n')
if self.message not in self.users_list.values():
self.users_list[fd]=self.message
self.poll.modify(self.sockets[fd],select.POLLOUT)
self.socket_state[fd]='connected'
else:
self.poll.modify(self.sockets[fd],select.POLLOUT)
self.socket_state[fd]='invalid nick'
if self.socket_state[fd]=='ready to communicate':
self.recv_until(fd,'\n')
print '5'
for i in self.users_list.keys():
if i!=fd:
self.poll.modify(self.sockets[i],select.POLLOUT)
self.socket_state[i]='ready to receive'
if __name__ == '__main__':
se=Server(sys.argv[1])
se.chat()
#! /usr/bin/env python
import sys,socket,select,threading,time
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
HOST=sys.argv.pop()
PORT=1060
class Client():
def setup(self):
server_address=(HOST,PORT)
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect(server_address)
def chat(self):
while True:
time.sleep(1)
text=raw_input('>>> ')
self.sock.sendall(text+'\n')
def rec(self):
while True:
mess=self.sock.recv(16)
if mess:
print '$$$ ', mess,
def start(self):
l=threading.Thread(target=self.rec)
t=threading.Thread(target=self.chat)
t.start()
l.start()
if __name__=='__main__':
cl=Client()
cl.setup()
cl.start()
Next time take a look at http://www.zeromq.org/, it has a nice python binding http://zeromq.github.com/pyzmq/. It's perfect for this kind of stuff.