Python sockets: sending and receving three multi messages at the same time - python

I'm working on a project to send some data from the server to the client, like name, age, and country as a messages to the client from the server.
I created this code using python and socket lib but I want to know are there any better ways to get the messages in the same order?
For example I'm sending a "first message" then "second message" then "third message" so the output should be in the same order: "first message" then "second message" then "third message"
Here is my code:
sending
import socket
UDP_IP = "127.0.0.1"
UDP_PORT = 5005
MESSAGE = "Hello, World!"
MESSAGE2 = "Hello, world2"
MESSAGE3 = "Hello, world3"
print "UDP target IP:", UDP_IP
print "UDP target port:", UDP_PORT
print "message:", MESSAGE
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE.encode(), (UDP_IP, UDP_PORT))
sock.sendto(MESSAGE2.encode(), (UDP_IP, UDP_PORT))
sock.sendto(MESSAGE3.encode(), (UDP_IP, UDP_PORT))
receiving
import socket
UDP_IP = "127.0.0.1"
UDP_PORT = 5005
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "received message:", data
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "received message:2", data
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "received message:3", data

instead of using udp use tcp which will make sure that the messages will be in order

Related

Receiving UDP packet without IP address

I'm trying to implement simple DHCP client. The problem is receiving UDP broadcast packets on network interface that hasn't assigned ip address yet.
I think I can simplify my issue to following scripts that I execute in docker containers working in the same bridge network.
sender.py:
import socket
UDP_IP = "255.255.255.255"
UDP_PORT = 5005
MESSAGE = b"Hello, World!"
print("UDP target IP: %s" % UDP_IP)
print("UDP target port: %s" % UDP_PORT)
print("message: %s" % MESSAGE)
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.setsockopt(socket.SOL_SOCKET, 25, str(f"eth1" + '\0').encode('utf-8'))
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
receiver.py:
import socket
UDP_IP = ""
UDP_PORT = 5005
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
sock.setsockopt(socket.SOL_SOCKET, 25, str(f"eth1" + '\0').encode('utf-8'))
while True:
data, addr = sock.recvfrom(1024)
print("received message: %s" % data)
If i execute upper scripts when ip address is statically assigned to eth1- interface (172.1.2.2) i receive packet. But after deleting ip address:
ip addr del 172.1.2.2/24 dev eth1
I can't receive anything.
Of course i can observe sent packet on eth1 on receiver side by tcpdump.
How can i receive UDP broadcast packet, on interface that doesn't have assigned ip address ?

Sending CAN frame via UDP in Python

I made UDP socket connection between two Linux machines and can send for example b"Hello, World!" easily. But now I need to send the below CAN frame
from can import Message
send_msg = Message(data=[1, 2, 3, 4, 5])
So if I print send_msg it shows:
Timestamp: 0.000000 ID: 00000000 X DLC: 5 01 02 03 04 05
I want to get this printed on the receiving end. The sending and receiving end codes I am using are below:
Sending:
import socket
UDP_IP = "10.140.189.249"
UDP_PORT = 5005
from can import Message
send_msg = Message(data=[1, 2, 3, 4, 5])
print(send_msg)
MESSAGE = send_msg
print("UDP target IP: %s" % UDP_IP)
print("UDP target port: %s" % UDP_PORT)
print("message: %s" % MESSAGE)
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
Here I know MESSAGE = send_msg is wrong.
Receiving
import socket
UDP_IP = "0.0.0.0"
UDP_PORT = 5005
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
rec_msg, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print("received message: %s" % rec_msg)
Please advise
As the physical layer of an UDP connection and a CAN connection are substantially different, you cannot send the CAN frames over UDP. What is of course possible is to send the payload of the CAN frame and assemble the CAN message on the receiving side: I.e. on the sending side:
sock.sendto(b“12345“, (UDP_IP, UDP_PORT))
And on the receiving side:
msg = Message(data=bytearray(recv_msg))
Most likely you do not only want to transfer the data of the CAN frame, but also the ids and other fields.
Another possibility would be to pickle the Message object on the sending side and unpickle it on the receiving side using pickle.dumps and pickle.loads
All features of the CAN bus like arbitration, error-frames etc. cannot be mimicked on a UDP connection.

broadcast a message among set of raspberry Pis

I want to broadcast a message among four raspberry Pis . I programmed the code By socket programming in python with UDP protocol . In order to send the message I used the broadcast IP address (192.168.0.255) and I test that in terminal on my computer it is work , but when I execute the same code on the Pi it is not working and no message is sent . When I send a message between two Pis and use (IP + port) it is work and the message is sent .
Did any one know what I must to change in my code ?? or in my Pi?? How I can broadcast this message ??
I also use the instruction (('', UDP_PORT)) and not work on Pi.
#Client.py
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM )
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
UDP_IP = "192.168.0.255"
UDP_PORT = 50000
MSG = 'Hello, World!'
MESSAGE = str.encode(MSG)
print (("message:"), MSG )
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
sock.close()
#server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
UDP_IP = "192.168.0.101"
UDP_PORT = 5005
s.bind((UDP_IP, UDP_PORT))
print('socket is created')
while True:
data ,addr = s.recvfrom(1024)
print (('received message:') , data.decode("utf-8"))

Establishing UDP communication with python

So, I have this code here. This sender script give's me the output properly.
import socket
UDP_IP = "127.0.0.1"
UDP_PORT = 0
MESSAGE = "Hi, can you listen to this?"
print "UDP target IP:", UDP_IP
print "UDP target port:", UDP_PORT
print "message:", MESSAGE
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
I tried to use this script on another host and try to establish a communication between the two. (Both the systems are on the same network ex. 00.000.00.xxx , only the xxx part varies)
import socket
UDP_IP = "127.0.0.1"
UDP_PORT = 0
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "received message:", data
Here is the output
Traceback (most recent call last):
File "C:/Users/bshivaku/Desktop/SEnd_Udp_packets.py", line 9, in <module>
sock.bind((UDP_IP, UDP_PORT))
File "C:\Python27\Lib\socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 10049] The requested address is not valid in its context
I used the ip address of the receiver on the sender script and sender ip address on receiver
I am sure I made a mistake with the UDP_PORT so i used PORT= 0 and tried. How to request for port number? How do I establish the connection? If not the port, where am I going wrong?
When sending a message use a specific port, for example UDP_PORT=8765, otherwise if UDP_PORT is set to 0 then the system will chose a random port for you.
Use the ip address of the receiver host in the sender script and bind to any interface on the receiver script.
On the receiving side use the same UDP port number configured in the sender script.
receiver:
import socket
UDP_IP = "0.0.0.0"
UDP_PORT = 8543
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "received message:", data
sender:
import socket
UDP_IP = "<ip_address_of_receiver>"
UDP_PORT = 8543
MESSAGE = "Hi, can you listen to this?"
print "UDP target IP:", UDP_IP
print "UDP target port:", UDP_PORT
print "message:", MESSAGE
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))
Aside the UDP addresses setting there are not any problems on python side.
About the error:
[Errno 10049] The requested address is not valid in its context
This normally stems from an attempt to bind to an address that is not valid for the local computer: so it seems that the loopback address 127.0.0.1 it is not configured on your machine.
Investigate on the sys admin side, for example check if the IPv4 network stack is enabled on your machine.

Cannot send and receive udp message in same program

I am able to send and receive UDP messages in separate programs, but I'm not able to do the same task in one program.
import socket
UDP_IP = "192.168.1.178"
UDP_PORT = 8888
msg = 'test'
print "UDP target IP: ", UDP_IP
print "UDP target PORT: ", UDP_PORT
print "Message: ", msg
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(msg, (UDP_IP, UDP_PORT))
UDP_IP2 = "192.168.1.198"
sock.bind((UDP_IP2, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "received message:", data
With this program, I am able to send UDP messages, however, I am not able to receive any messages from the other machine.
What am I doing wrong?
Thanks in advance,
Mikkel
In your example you try to bind socket addr after sending, what's wrong.
Address can be bound to socket only before any data transfer.
If there is no explicit bind OS sets any free (unused) port number in range [1024, 65535] on first .send()/.recv() call.
Next, socket can be bound only to single IP (except special case '0.0.0.0' which means "all host's interfaces").

Categories

Resources