Sometimes I have to send a message to a specific IP and sometimes I have to broadcast the message to all the IP's in my network. At the other end I have to distinguish between a broadcast and a normal one, but recvfrom() just returns the address the message came from;
there is no difference between them. Can anyone help me distinguish them?
UDP is the protocol.
I don't think it's possible with Python's socket module. UDP is a very minimalistic protocol, and the only way to distinguish between a broadcast and a non-broadcast UDP packet is by looking at the destination address. However, you cannot inspect that part of the packet with the BSD socket API (if I remember it correctly), and the socket module exposes the BSD socket API only. Your best bet would probably be to use the first byte of the message to denote whether it is a broadcast or a unicast message.
Related
I want to implement pbft algorithm(3f+1 systems;f=1) in python. But what is the channel should use for sending and receiving from replicas. I have tried python multicast but it seems something going wrong while receiving. So please suggest any solution that can put me forward.
Thanks in Advance.
You need to use authenticated point-to-point communication channel to implement any sorts of BFT algorithm. Because PBFT assumes all participant's identity are established in prior, you don't need to assume multicast communication primitive. Even though broadcast is executed in PBFT protocol, each message is encrypted by its private key. So you don't need to use multicast or broadcast.
I have a multicast server sending data that must be captured by a python client. The problem is that recvfrom does not receive any data or at least receive the first packet and sorta caches it. If I use recvfrom in a loop then my data is received correctly.
My question is why I should use recvfrom in a loop to have the expected behavior?
from socket import *
s=socket(AF_INET, SOCK_DGRAM)
s.bind(('172.30.102.141',12345))
m=s.recvfrom(1024)
print m[0]
# sleep for x seconds here
m=s.recvfrom(1024)
print m[0]
# print the exact same thing as previously...
One thing is for sure, multicast is basically sending UDP packages and you have to keep listening for new packages. That is true even for TCP protocol based communication.
When you use low level interfaces for network communication, like socket is, it's up on both sides to define application level protocol.
That means, you define how receiving party concludes that message is complete. This is because message could get split in multiple parts/packets that get through the network. So receiving side has to assemble them in a proper way and then check if the message is whole. After that you push it up through the pipeline of processing messages or whatever you do in receiving side.
When using UDP, receiving side doesn't know if there is any packet on its way, so it just does try to recvfrom 1024 bytes and finishes. It doesn't know and should not care if there is more data on it's way. It's up to you to take care of that.
I am working on a project where I have a client server model in python. I set up a server to monitor requests and send back data. PYZMQ supports: tcp, udp, pgm, epgm, inproc and ipc. I have been using tcp for interprocess communication, but have no idea what i should use for sending a request over the internet to a server. I simply need something to put in:
socket.bind(BIND_ADDRESS)
DIAGRAM: Client Communicating over internet to server running a program
Any particular reason you're not using ipc or inproc for interprocess communication?
Other than that, generally, you can consider tcp the universal communicator; it's not always the best choice, but no matter what (so long as you actually have an IP address) it will work.
Here's what you need to know when making a choice between transports:
PGM/EPGM are multicast transports - the idea is that you send one message and it gets delivered as a single message until the last possible moment where it will be broken up into multiple messages, one for each receiver. Unless you absolutely know you need this, you don't need this.
IPC/Inproc are for interprocess communication... if you're communicating between different threads in the same process, or different processes on the same logical host, then these might be appropriate. You get the benefit of a little less overhead. If you might ever add new logical hosts, this is probably not appropriate.
Russle Borogove enumerates the difference between TCP and UDP well. Typically you'll want to use TCP. Only if absolute speed is more important than reliability then you'll use UDP.
It was always my understanding that UDP wasn't supported by ZMQ, so if it's there it's probably added by the pyzmq binding.
Also, I took a look at your diagram - you probably want the server ZMQ socket to bind and the client ZMQ socket to connect... there are some reasons why you might reverse this, but as a general rule the server is considered the "reliable" peer, and the client is the "transient" peer, and you want the "reliable" peer to bind, the "transient" peer to connect.
Over the internet, TCP or UDP are the usual choices. I don't know if pyzmq has its own delivery guarantees on top of the transport protocol. If it doesn't, TCP will guarantee in-order delivery of all messages, while UDP may drop messages if the network is congested.
If you don't know what you want, TCP is the simplest and safest choice.
I browsed the python socket docs and google for two days but I did not find any answer. Yeah I am a network programming newbie :)
I would like to implement some LAN chatting system with specific function for our needs. I am at the very beginning. I was able to implement a client-server model where the client connects to the server (socket.SOCK_STREAM) and they are able to change messages. I want to step forward. I want the client to discover the LAN with a broadcast how many other clients are available.
I failed. Is it possible that a socket.SOCK_STREAM type socket could not be used for this task?
If so, what are my opportunities? using udp packets? How I have to listen for brodcast messages/packets?
The broadcast is defined by the destination address.
For example if your own ip is 192.168.1.2, the broadcast address would be 192.168.1.255 (in most cases)
It is not related directly to python and will probably not be in its documentation. You are searching for network "general" knowledge, to a level much higher than sockets programming
*EDIT
Yes you are right, you cannot use SOCK_STREAM. SOCK_STREAM defines TCP communication. You should use UDP for broadcasting with socket.SOCK_DGRAM
How do you get a socket to receive packets destined for the IPv6 Subnet-Routers Anycast address?
I haven't been able to find any informationn on how to do this.
In a fit of desparation, I've tried using socket.setsockopt as you would to join a multicast group:
# 7 is the interface number
s = socket(AF_INET6, SOCK_DGRAM)
packed_iface_num = struct.pack("I", 7)
group = inet_pton(AF_INET6, 'fd36:d00d:d00d:47cb::') + packed_iface_num
# socket.error: (22, 'Invalid argument')
s.setsockopt(IPPROTO_IPV6, IPV6_JOIN_GROUP, group)
And also using bind
# socket.error: (99, 'Cannot assign requested address')
s.bind(('fd36:773e:6b4c:47cb::', 9876))
As expected, neither of these worked. Is there a way to do this?
Instead of IPV6_JOIN_GROUP, try passing IPV6_JOIN_ANYCAST to your s.setsockopt() code. Unfortunately the Python socket module doesn't define it but you should be able to pass the integer equivalent instead. In Linux IPV6_JOIN_ANYCAST is 27 and IPV6_LEAVE_ANYCAST is 28. (defined in /usr/include/linux/in6.h)
The best documentation I could find is from this lkml e-mail describing the anycast patch to the Linux kernel:
The application interface for joining and leaving anycast groups is 2
new setsockopt() calls: IPV6_JOIN_ANYCAST and IPV6_LEAVE_ANYCAST. The arguments
are the same as the corresponding multicast operations.
May the dancing kame be with you!
The IPV6_JOIN_ANYCAST and IPV6_LEAVE_ANYCAST socket options are non-standard Linux-isms.
If you'd like your code to be portable, then you should probably do it the standard way, i.e. assign the subnet routers anycast address to the appropriate interface, then bind your socket to the wildcard address and discard everything not sent to the subnet router anycast address. Remember, you're not supposed to send packets with the anycast address in the source field, and you can't open a read-only socket in the standard sockets API.
Assigning an interface address should be a privileged operation on any reasonable operating system, and that's the part that isn't going to be standard whatever you do. If you must do that programmatically, then it will mean (on BSD for example) using something like the SIOCAIFADDR_IN6 code and the ioctl() system call. Make sure to set the IN6_IFF_ANYCAST flag in the ifra_flags field of the interface alias request structure.