Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Boring Network Tool #34

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
20 changes: 20 additions & 0 deletions Tools/boringNetworkTool/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Boring Network Tool
colton-smith marked this conversation as resolved.
Show resolved Hide resolved

The file main.py can be used to send either
TCP or UDP messages to a given hostname and port, specified via the config json.

This script does not require any external packages, aside from standard python 3.7 or higher.

Usage:

sending_config.json
has a similar configuration to the json in Pidaq/Examples/CanSender, and can be used to specify the
messages to send, and whether to send them via TCP or UDP. The frequency with which to send the
messages can also be specified. Finally, the port and hostname are specified in the json as well.

tcp_server.py implements a simple TCP server to verify the functionality of the script.

udp_server.py implements a simple UDP server to verify the functionality of the script.

For both server scripts, to receive any messages and print them out, simply use localhost
and port 8888 to connect to the server after running it
83 changes: 83 additions & 0 deletions Tools/boringNetworkTool/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import socket
import sys
import time
import json
Comment on lines +1 to +4
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably want to order these in alphabetical order



class Message:
def __init__(self, msgID, isExtendedID, data):
mjswen0923 marked this conversation as resolved.
Show resolved Hide resolved
self.msgID = msgID
self.isExtendedID = isExtendedID
self.data = data
def toString(self):
mjswen0923 marked this conversation as resolved.
Show resolved Hide resolved
return "" + str(self.msgID) + "\n" + str(self.isExtendedID) + "\n" + str(self.data)

def createMessages(raw_messages):
msgs = []
for message in raw_messages:
msgs.append(Message(msgID=message["msgId"],
isExtendedID=message["isExtendedId"],
data=message["data"]
))
return msgs


mjswen0923 marked this conversation as resolved.
Show resolved Hide resolved
def sendWithUDP(msg_config, host, port):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except socket.error:
print('Failed to create socket')
sys.exit()
msgs = createMessages(msg_config["config"]["messages"])
msg_frequency = msg_config["config"]["messageFrequency"]
for message in msgs:
time.sleep(1.0 / msg_frequency)
try:
# Set the whole string
s.sendto(bytes(message.toString(), 'utf-8'), (host, port))
print("message sent:" + message.toString())
# receive data from client (data, addr)
d = s.recvfrom(1024)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This blocks, with UDP I don't think we will always want to wait for a reply from the server before sending the next packet. Potentially, we could have an option in the config to await a reply.

Where it is a debug tool, we will usually just want it to send data continuously as well. This could be another option in the config (bool sendContinuous), that if true the script just continuously calls sendUDP or sendTCP.

I tried a while loop, it worked fine for UDP but there was an error when calling send TCP in a while loop (the server reset the connection or something)

image

reply = d[0]
addr = d[1]
print('Server reply : ' + reply.decode('utf-8'))
except socket.error as msg:
print('Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
mjswen0923 marked this conversation as resolved.
Show resolved Hide resolved
sys.exit()

def sendWithTCP(msg_config, host, port):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
except socket.error:
print('Failed to create socket')
sys.exit()
msgs = createMessages(msg_config["config"]["messages"])
msg_frequency = msg_config["config"]["messageFrequency"]
for message in msgs:
time.sleep(1.0 / msg_frequency)
try:
# Set the whole string
s.sendall(bytes(message.toString(), 'utf-8'))
print("message sent:" + message.toString())
# receive data from client (data, addr)
d = s.recv(1024)
print('Server reply : ' + d.decode('utf-8'))
except socket.error as msg:
print('Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
s.close()
sys.exit()
s.close()


if __name__ == "__main__":
with open('sending_config.json', mode='r') as json_config:
msg_config = json.load(json_config)
host = msg_config["config"]["ip"]
port = msg_config["config"]["port"]
useTCP = msg_config["config"]["useTCP"]
print("Using TCP: " + str(useTCP))
if useTCP:
sendWithTCP(msg_config, host, port)
else:
sendWithUDP(msg_config, host, port)
63 changes: 63 additions & 0 deletions Tools/boringNetworkTool/sending_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"config": {
"ip": "localhost",
"port": 8888,
"useTCP": false,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be better if this is commsType, or something similar, and then it parses for TCP or UDP as the value. If you make the option to act as the tcp server, you could then have a setting called servePort which would determine that.

"messageFrequency": 5,
"messages": [
{
"msgId": 5,
"isExtendedId": 0,
mjswen0923 marked this conversation as resolved.
Show resolved Hide resolved
"data": [
5,
6,
7,
8,
9,
10
]
},
{
"msgId": 100,
"isExtendedId": 0,
"data": [
72,
54,
32,
87
]
},
{
"msgId": 200,
"isExtendedId": 0,
"data": [
100,
253,
0,
87
]
},
{
"msgId": 74,
"isExtendedId": 0,
"data": [
87
]
},
{
"msgId": 29,
"isExtendedId": 0,
"data": [
98,
56,
182,
78,
28,
37,
16,
82
]
}
]
}
}
mjswen0923 marked this conversation as resolved.
Show resolved Hide resolved
29 changes: 29 additions & 0 deletions Tools/boringNetworkTool/tcp_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import socket
import sys

HOST = ''
mjswen0923 marked this conversation as resolved.
Show resolved Hide resolved
PORT = 8888

try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')
except socket.error as msg:
print('Failed to create socket. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
sys.exit()

try:
s.bind((HOST, PORT))
except socket.error as msg:
print('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
sys.exit()


s.listen(1)
conn, addr = s.accept()
while 1:
data = conn.recv(1024)
print("Data received: " + data.decode('utf-8'))
if not data:
break
conn.sendall(data)
conn.close()
mjswen0923 marked this conversation as resolved.
Show resolved Hide resolved
32 changes: 32 additions & 0 deletions Tools/boringNetworkTool/udp_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import socket
import sys

HOST = ''
mjswen0923 marked this conversation as resolved.
Show resolved Hide resolved
PORT = 8888

try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
print('Socket created')
except socket.error as msg:
print('Failed to create socket. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
sys.exit()

try:
s.bind((HOST, PORT))
except socket.error as msg:
print('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
sys.exit()

while 1:
d = s.recvfrom(1024)
data = d[0]
addr = d[1]
if not data:
break

print("Data received: " + data.decode('utf-8'))
reply = 'OK...' + data.decode('utf-8')
s.sendto(bytes(reply, 'utf-8'), addr)
print('Message[' + addr[0] + ':' + str(addr[1]) + '] - ' + data.decode('utf-8').strip())
mjswen0923 marked this conversation as resolved.
Show resolved Hide resolved

s.close()