mark
mark

Reputation: 1

Python: UDP socket's recvfrom returning localhost or external IP

I have a client program that uses two UDP sockets, one for listening and the other for writing.

OUT_SOCKET = socket(AF_INET, SOCK_DGRAM) # write-only UDP
IN_SOCKET = socket(AF_INET, SOCK_DGRAM) # read-only UDP

I run the program on localhost on two different ports and send messages to each other.

OUT_SOCKET.sendto(some_msg, (ip, port))

And I read the message like this.

msg, addr = IN_SOCKET.recvfrom(MAX_MSG_SIZE)

The problem is, when I specify 127.0.0.1 for the ip (for sending some_msg), on the receiving client, the addr is set to 127.0.0.1. But when I specify ip to 192.168.X.X (my external IP address) from sending client, the receiving client's addr is set to 192.168.X.X.

I expect addr to be consistent no matter how ip is set. Does recvfrom behave differently depending on how the sender specifies the ip address?

How does recvfrom extract remote address? What's causing recvfrom to behave differently?

Upvotes: 0

Views: 2085

Answers (1)

D.Shawley
D.Shawley

Reputation: 59573

The address returned from recvfrom is specifically the source IP address in the packet received. When you send a UDP packet using sendto, the IP stack will choose the appropriate interface to send the packet from. recvfrom is not behaving differently, sendto choose the source network interface based on IP routing rules.

In your case, you have two network interfaces -- one that is listening for packets with a destination address of 127.0.0.1 and another that is listening on 192.168.x.y. When you send a packet using sendto, it has to originate from a network interface that can route to the destination address.

When you send a packet to 127.0.0.1, it will originate from the loopback address (e.g., 127.0.0.1). When you send a packet to 192.168.x.y, it will originate from the second network interface. In both cases, the peer IP address returned from recvfrom identifies the sending network interface.

Upvotes: 1

Related Questions