I need help to get data sent from an instrument via udp protocol - sockets

i have an instrument that measures so2 and i have a standard program that makes me see the data, but i need to connect the instrument to a server and send all the data to a database. I used wireshark to see how it comunicate with the software, but i don't understand what method to use to make my program. Here i have the wireshark dump:
the red circle indicates the measure that the instrument made.
P.S. sorry for my bad eng

So i solved my question as i'm about to show:
i made a listener and a caller;
caller:
`from socket import socket, AF_INET, SOCK_DGRAM
SERVER_IP = '192.168.1.99'
PORT_NUMBER = 53700
SIZE = 1024
print ("Test client sending packets to IP {0}, via port {1}\n".format(SERVER_IP, PORT_NUMBER))
mySocket = socket( AF_INET, SOCK_DGRAM )
mySocket.bind(('192.168.1.100', 57806))
while True:
data = bytes.fromhex('014630303430335230303102313103')
mySocket.sendto(data,(SERVER_IP,PORT_NUMBER))
exit()`
listener:
`from socket import socket, gethostbyname, AF_INET, SOCK_DGRAM
import sys
PORT_NUMBER = 57806
SIZE = 1024
hostName = gethostbyname( '' )
mySocket = socket( AF_INET, SOCK_DGRAM )
mySocket.bind( (hostName, PORT_NUMBER) )
print ("Test server listening on port {0}\n".format(PORT_NUMBER))
while True:
(data,addr) = mySocket.recvfrom(SIZE)
print (data)
sys.ext()`
i saw on wireshark that if i sent a request packet copied from the ones that i already have, the instrument would give me back the response; so i setupped a listener on the a choosen port, and now i get all the data!
the highlighted packet is the one i sent from the caller script.

Related

Create UDP client socket without socket listening

I'm using the standard way, shown in many examples, to create a UDP socket in C++, keep it alive and keep sending stuff over it.
I only call sendto. I never call recvfrom. In this code fragment I only use sendto once and then sleep for 5 seconds:
C code:
static int do_the_rest( int sock )
{
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr=inet_addr("192.168.32.32");
server_addr.sin_port=htons(32000);
char sendline[100];
bzero(sendline,sizeof(sendline));
const struct sockaddr * addr = (const struct sockaddr*)&server_addr;
sendto(sock,sendline,sizeof(sendline),0,addr,sizeof(server_addr));
sleep( 5 );
return 0;
}
int main(int argc, char**argv)
{
int sock;
sock=socket(AF_INET,SOCK_DGRAM,0);
if( sock < 0 ) {
perror( "socket" );
return 1;
}
int ret = do_the_rest( sock );
close( sock );
return ret;
}
Now, if I run "netstat -na", I can identify that the system seems to listen on the local port of the socket (I remove the lines in my program that print the local port, for clarity):
netstat -na:
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
...
udp 0 304 0.0.0.0:53735 0.0.0.0:*
When I try something similar in Java, I also seem to get some listening, although it looks a bit different (perhaps IPv6?):
Java code:
import java.io.*;
import java.net.*;
class Udp {
public static void main(String[] args) throws Throwable {
DatagramSocket sock = new DatagramSocket(null);
try {
InetAddress ipAddress = InetAddress.getByName("192.168.32.32");
byte[] sendData = new byte[50000];
DatagramPacket sendPacket = new DatagramPacket(
sendData, sendData.length, ipAddress, 32000);
sock.send(sendPacket);
Thread.sleep(5000);
} finally {
sock.close();
}
}
}
netstat -na:
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
...
udp 0 0 :::37053 :::*
I understand this is done in order to support a possible recvfrom (receive in Java) that may follow. However, is there a way to tell the socket not to listen to incoming packets at all?
Thanks
Now, if I run "netstat -na", I can identify that the system seems to listen on the local port of the socket
UDP sockets have a kernel buffer for incoming messages. This buffer is maintained by the kernel regardless whether you call recv/recvfrom/recvmsg from user-space code.
You can use shutdown() with its how parameter set to SHUT_RD to disable reads on the socket, which may have the intended behavior of stopping the listening, maybe even freeing the kernel's receive buffer. But the receive port has to remain allocated for the socket's lifetime, as it is used as the source port for the outgoing packets you are sending with sendto(). You cannot avoid that.
It is not only 'listening' on that port, it is sending via that port. The port allocation is required. The socket gets bound to a port as soon as you call sendto(), unless it is already bound.

Socket use in python

I want to create a chat program between two machines. I am using machine one which has the IP address 192.168.0.5, I can successfully send a message to machine two 192.168.0.2, and then send a message in response from machine two, to machine 1.
However I encountered a problem on the second send attempt from either machine, (noticing that before sending the second time I wait for a response from the initial send) claiming that the IP address is already in use or connection is refused, how can this be changed so that a defined number of choices can be sent?
I appreciate that the following code is not the most efficient way of sending and receiving multiple messages, that would be some description of for loop. For example for sendAndRecieve in range(0,5).
The two machines are linked using ethernet cables running through a switch and the code is run simultaneously.
Machine 1 code:
#Sending first message
host = "192.168.0.5"
port = 4446
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind((host,port))
s.listen(1)
print("listening")
q,addr = s.accept(1024)
data = "This is the first message I am sending"
data = data.encode("utf-8")
q.send(data)
s.close
#Recieving response message 1
while True:
try:
host = "192.168.0.2"
port = 4446
from socket import*
s = socket(AF_INET, SOCK_STREAM)
s.connect((host,port))
msg = s.recv(1024)
msg = msg.decode("utf-8")
print(msg)
s.close()
except:
pass
#Sending second message this is where the problem happens
host = "192.168.0.5"
port = 4446
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind((host,port))
s.listen(1)
print("listening")
q,addr = s.accept(1024)
data = "This is the first message I am sending"
data = data.encode("utf-8")
q.send(data)
s.close
Machine 2 code:
#Recieving message 1
while True:
try:
host = "192.168.0.5"
port = 4446
from socket import*
s = socket(AF_INET, SOCK_STREAM)
s.connect((host,port))
msg = s.recv(1024)
msg = msg.decode("utf-8")
print(msg)
s.close()
except:
pass
#Sending first message
host = "192.168.0.2"
port = 4446
from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind((host,port))
s.listen(1)
print("listening")
q,addr = s.accept(1024)
data = "This is the first message I am sending"
data = data.encode("utf-8")
q.send(data)
s.close
#Recieving response message 1 this is where the problem happens
while True:
try:
host = "192.168.0.25"
port = 4446
from socket import*
s = socket(AF_INET, SOCK_STREAM)
s.connect((host,port))
msg = s.recv(1024)
msg = msg.decode("utf-8")
print(msg)
s.close()
except:
pass
Reading through your code, I don't see how Machine 2's while loop will ever stop trying to receive data from Machine 1 (there's no break in the loop other than if an error is encountered). Machine 1 does continue on after Machine 2 connects the first time, but then tries to connect to Machine 2 while Machine 2 is trying to connect to Machine 1. That's probably the cause of the error that you're seeing, and why you only see the first message sent/received.

asyncio project. What am I missing?

I've been working on a client for this chat server but I am running into a bit of a challenge. The server uses Python's 3.4RC1 asyncio module.
Behavior:
My client connects. My second client connects. Either can send messages to the server BUT, the server is not broadcasting them as it should in a normal public chat room.
User1: Hello. Presses Enter.
User2 does not see it.
User2: Anyone there? Presses Enter.
User2 sees User1: Hello. and User2: Anyone there?
Just... strange. Not sure what I'm missing.
Here are the files. Give it a try.
Server:
from socket import socket, SO_REUSEADDR, SOL_SOCKET
from asyncio import Task, coroutine, get_event_loop
class Peer(object):
def __init__(self, server, sock, name):
self.loop = server.loop
self.name = name
self._sock = sock
self._server = server
Task(self._peer_handler())
def send(self, data):
return self.loop.sock_send(self._sock, data.encode('utf-8'))
#coroutine
def _peer_handler(self):
try:
yield from self._peer_loop()
except IOError:
pass
finally:
self._server.remove(self)
#coroutine
def _peer_loop(self):
while True:
buf = yield from self.loop.sock_recv(self._sock, 1024)
if buf == b'':
break
self._server.broadcast('%s: %s' % (self.name, buf.decode('utf-8')))
class Server(object):
def __init__(self, loop, port):
self.loop = loop
self._serv_sock = socket()
self._serv_sock.setblocking(0)
self._serv_sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
self._serv_sock.bind(('',port))
self._serv_sock.listen(5)
self._peers = []
Task(self._server())
def remove(self, peer):
self._peers.remove(peer)
self.broadcast('Peer %s quit!' % (peer.name,))
def broadcast(self, message):
for peer in self._peers:
peer.send(message)
#coroutine
def _server(self):
while True:
peer_sock, peer_name = yield from self.loop.sock_accept(self._serv_sock)
peer_sock.setblocking(0)
peer = Peer(self, peer_sock, peer_name)
self._peers.append(peer)
self.broadcast('Peer %s connected!' % (peer.name,))
def main():
loop = get_event_loop()
Server(loop, 1234)
loop.run_forever()
if __name__ == '__main__':
main()
Client:
# import socket
from socket import *
# form socket import socket, bind, listen, recv, send
HOST = 'localhost' #localhost / 192.168.1.1
# LAN - 192.168.1.1
PORT = 1234
s = socket(AF_INET, SOCK_STREAM)# 98% of all socket programming will use AF_INET and SOCK_STREAM
s.connect((HOST, PORT))
while True:
message = input("Your Message: ")
encoded_msg = message.encode('utf-8')
s.send(encoded_msg)
print('Awaiting Reply..')
reply = s.recv(1024)
decoded_reply = reply.decode('utf-8')
decoded_reply = repr(decoded_reply)
print('Received ', decoded_reply)
s.close()
Here's the non threaded server code I wrote. works great but ONLY between 2 people. How could this code be updated to broadcast every message received to all clients connected?
# import socket
from socket import *
# form socket import socket, bind, listen, recv, send
HOST = 'localhost' #localhost / 192.168.1.1
# LAN - 192.168.1.1
PORT = 1234
s = socket(AF_INET, SOCK_STREAM) # 98% of all socket programming will use AF_INET and SOCK_STREAM
s.bind((HOST, PORT))
s.listen(5) # how many connections it can receive at one time
conn, addr = s.accept() # accept the connection
print('Connected by', addr) # print the address of the person connected
while True:
data = conn.recv(1024)
decoded_data = data.decode('utf-8')
data = repr(decoded_data)
print('Received ', decoded_data)
reply = input("Reply: ")
encoded_reply = reply.encode('utf-8')
conn.sendall(encoded_reply)
print('Server Started')
conn.close()
Okay, let’s think about what your client does. You ask for a message to send, blocking for user input. Then you send that message and receive whatever there is at the server. Afterwards, you block again, waiting for another message.
So when client A sends a text, client B is likely blocking for user input. As such, B won’t actually check if the server sent anything. It will only display what’s there after you have sent something.
Obviously, in a chat, you don’t want to block on user input. You want to continue receiving new messages from the server even if the user isn’t sending messages. So you need to separate those, and run both asynchronously.
I haven’t really done much with asyncio yet, so I don’t really know if this can be nicely done with it, but you essentially just need to put the reading and sending into two separate concurrent tasks, e.g. using threads or concurrent.futures.
A quick example of what you could do, using threading:
from socket import *
from threading import Thread
HOST = 'localhost'
PORT = 1234
s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT))
def keepReading ():
try:
while True:
reply = s.recv(1024).decode()
print('Received ', reply)
except ConnectionAbortedError:
pass
t = Thread(target=keepReading)
t.start()
try:
while True:
message = input('')
s.send(message.encode())
except EOFError:
pass
finally:
s.close()

How to change a socket's IP_MULTICAST_IF

I have a Computer with 5 interfaces: 3 with public IPs and 2 local IPs. I am trying to send "HELLO" to a UDP server, but I would like to change the interface to one of the local IP addresses. I did some research and this is the line I need to add in python:
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton("64.195.10.11"))
with 64.195.10.11 being the IP I want to change to
So my python code looks like this:
import socket
MCAST_GRP = '224.0.0.1'
MCAST_PORT = 10222
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton("64.195.10.10"))
sock.sendto("HELLO", (MCAST_GRP, MCAST_PORT))
It works perfectly when I change between my 3 public IP addresses. However, it does not work (packet is not delivered) if I put a local IP in the argument. I am not sure if the script does not send, or the server does not receive. What is happening?
SL
Edit: I am listening using two ways:
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("", 10222))
sock.setsockopt(socket.IPPROTO_IP,
socket.IP_ADD_MEMBERSHIP,
socket.inet_aton("224.0.0.1") +
socket.inet_aton("64.195.10.11"))
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0)
while True:
print >>sys.stderr, '\nwaiting to receive message'
data, address = sock.recvfrom(1024)
print >>sys.stderr, 'received %s bytes from %s' % (len(data), address)
print >>sys.stderr, data
print >>sys.stderr, 'sending acknowledgement to', address
sock.sendto('ack', address)
and using twisted:
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
from twisted.application.internet import MulticastServer
class MulticastServerUDP(DatagramProtocol):
def __init__ (self, group, name):
self.group = group
self.name = name
def startProtocol(self):
print '%s Started Listening' % self.group
self.transport.joinGroup(self.group)
def datagramReceived(self, datagram, address):
print "%s Received:"%self.name + repr(datagram) + repr(address)
reactor.listenMulticast(10222, MulticastServerUDP('224.0.0.1', 'SERVER1'), listenMultiple = True)
reactor.run()
In case the server and the client are on the same machine (for testing), maybe you need to set IP_MULTICAST_LOOP option like this (c Code):
int loop_on = 1;
setsockopt(socket, IPPROTO_IP, IP_MULTICAST_LOOP, &loop_on, sizeof(loop_on));
In python you can try something like this:
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
Hope this help.
Edit : Adding some trace (From my Linux box)
The code i use is the same as posted by SquallLeohart:
#! /usr/bin/python
import socket
MCAST_GRP = '224.0.0.1'
MCAST_PORT = 10222
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton("192.168.1.7"))
sock.sendto("HELLO", (MCAST_GRP, MCAST_PORT))
And:
#! /usr/bin/python
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("", 10222))
sock.setsockopt(socket.IPPROTO_IP,
socket.IP_ADD_MEMBERSHIP,
socket.inet_aton("224.0.0.1") +
socket.inet_aton("192.168.1.7"))
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0)
while True:
print >>sys.stderr, '\nwaiting to receive message'
data, address = sock.recvfrom(1024)
print >>sys.stderr, 'received %s bytes from %s' % (len(data), address)
print >>sys.stderr, data
print >>sys.stderr, 'sending acknowledgement to', address
sock.sendto('ack', address)
I got this output :
waiting to receive message
received 5 bytes from ('192.168.1.7', 43761)
HELLO
sending acknowledgement to ('192.168.1.7', 43761)
waiting to receive message
received 5 bytes from ('192.168.1.7', 52326)
HELLO
sending acknowledgement to ('192.168.1.7', 52326)
waiting to receive message
And with tcpdump:
21:01:33.814728 IP localhost.localdomain.34956 > all-systems.mcast.net.10222: UDP, length 5
21:01:35.364605 IP localhost.localdomain.39078 > all-systems.mcast.net.10222: UDP, length 5
21:01:36.228477 IP localhost.localdomain.49926 > all-systems.mcast.net.10222: UDP, length 5
Regards.
The answer: my firewall did not accept udp packet from that RFC1918 IP address.

Python Socket Multiple Clients

So I am working on an iPhone app that requires a socket to handle multiple clients for online gaming. I have tried Twisted, and with much effort, I have failed to get a bunch of info to be sent at once, which is why I am now going to attempt socket.
My question is, using the code below, how would you be able to have multiple clients connected? I've tried lists, but I just can't figure out the format for that. How can this be accomplished where multiple clients are connected at once and I am able to send a message to a specific client?
Thank you!
#!/usr/bin/python # This is server.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 50000 # Reserve a port for your service.
print 'Server started!'
print 'Waiting for clients...'
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
while True:
msg = c.recv(1024)
print addr, ' >> ', msg
msg = raw_input('SERVER >> ')
c.send(msg);
#c.close() # Close the connection
Based on your question:
My question is, using the code below, how would you be able to have multiple clients connected? I've tried lists, but I just can't figure out the format for that. How can this be accomplished where multiple clients are connected at once and I am able to send a message to a specific client?
Using the code you gave, you can do this:
#!/usr/bin/python # This is server.py file
import socket # Import socket module
import thread
def on_new_client(clientsocket,addr):
while True:
msg = clientsocket.recv(1024)
#do some checks and if msg == someWeirdSignal: break:
print addr, ' >> ', msg
msg = raw_input('SERVER >> ')
#Maybe some code to compute the last digit of PI, play game or anything else can go here and when you are done.
clientsocket.send(msg)
clientsocket.close()
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 50000 # Reserve a port for your service.
print 'Server started!'
print 'Waiting for clients...'
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
print 'Got connection from', addr
while True:
c, addr = s.accept() # Establish connection with client.
thread.start_new_thread(on_new_client,(c,addr))
#Note it's (addr,) not (addr) because second parameter is a tuple
#Edit: (c,addr)
#that's how you pass arguments to functions when creating new threads using thread module.
s.close()
As Eli Bendersky mentioned, you can use processes instead of threads, you can also check python threading module or other async sockets framework. Note: checks are left for you to implement how you want and this is just a basic framework.
accept can continuously provide new client connections. However, note that it, and other socket calls are usually blocking. Therefore you have a few options at this point:
Open new threads to handle clients, while the main thread goes back to accepting new clients
As above but with processes, instead of threads
Use asynchronous socket frameworks like Twisted, or a plethora of others
Here is the example from the SocketServer documentation which would make an excellent starting point
import SocketServer
class MyTCPHandler(SocketServer.BaseRequestHandler):
"""
The RequestHandler class for our server.
It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
"""
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print "{} wrote:".format(self.client_address[0])
print self.data
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper())
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
Try it from a terminal like this
$ telnet localhost 9999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello
HELLOConnection closed by foreign host.
$ telnet localhost 9999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Sausage
SAUSAGEConnection closed by foreign host.
You'll probably need to use A Forking or Threading Mixin too
This program will open 26 sockets where you would be able to connect a lot of TCP clients to it.
#!usr/bin/python
from thread import *
import socket
import sys
def clientthread(conn):
buffer=""
while True:
data = conn.recv(8192)
buffer+=data
print buffer
#conn.sendall(reply)
conn.close()
def main():
try:
host = '192.168.1.3'
port = 6666
tot_socket = 26
list_sock = []
for i in range(tot_socket):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind((host, port+i))
s.listen(10)
list_sock.append(s)
print "[*] Server listening on %s %d" %(host, (port+i))
while 1:
for j in range(len(list_sock)):
conn, addr = list_sock[j].accept()
print '[*] Connected with ' + addr[0] + ':' + str(addr[1])
start_new_thread(clientthread ,(conn,))
s.close()
except KeyboardInterrupt as msg:
sys.exit(0)
if __name__ == "__main__":
main()
def get_clients():
first_run = True
startMainMenu = False
while True:
if first_run:
global done
done = False
Thread(target=animate, args=("Waiting For Connection",)).start()
Client, address = objSocket.accept()
global menuIsOn
if menuIsOn:
menuIsOn = False # will stop main menu
startMainMenu = True
done = True
# Get Current Directory in Client Machine
current_client_directory = Client.recv(1024).decode("utf-8", errors="ignore")
# beep on connection
beep()
print(f"{bcolors.OKBLUE}\n***** Incoming Connection *****{bcolors.OKGREEN}")
print('* Connected to: ' + address[0] + ':' + str(address[1]))
try:
get_client_info(Client, first_run)
except Exception as e:
print("Error data received is not a json!")
print(e)
now = datetime.now()
current_time = now.strftime("%D %H:%M:%S")
print("* Current Time =", current_time)
print("* Current Folder in Client: " + current_client_directory + bcolors.WARNING)
connections.append(Client)
addresses.append(address)
if first_run:
Thread(target=threaded_main_menu, daemon=True).start()
first_run = False
else:
print(f"{bcolors.OKBLUE}* Hit Enter To Continue.{bcolors.WARNING}\n#>", end="")
if startMainMenu == True:
Thread(target=threaded_main_menu, daemon=True).start()
startMainMenu = False
#!/usr/bin/python
import sys
import os
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 50000
try:
s.bind((socket.gethostname() , port))
except socket.error as msg:
print(str(msg))
s.listen(10)
conn, addr = s.accept()
print 'Got connection from'+addr[0]+':'+str(addr[1]))
while 1:
msg = s.recv(1024)
print +addr[0]+, ' >> ', msg
msg = raw_input('SERVER >>'),host
s.send(msg)
s.close()