How to get broadcast address with python socket in localhost? - python

I try to send messages in localhost to broadcast address, but it does not work. When I use socket.INADDR_BROADCAST, I get [Errno 11001] getaddrinfo failed.
import socket
client_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_server.bind(("127.0.0.1", 12345))
client_server.connect((f"{socket.INADDR_BROADCAST}", 12345))
client_server.sendto("New user is connected".encode("utf-8"), (f"{socket.INADDR_BROADCAST}", 12345))

You are creating a TCP (SOCK_STREAM) socket. TCP has no notion of broadcasting. A TCP client socket cannot connect() to a broadcast IP, and a TCP server socket cannot listen() on a broadcast IP. That just makes no sense to do. The only way to broadcast a message in TCP is for the server to keep track of each client connected to it and then send the message to each client one at a time.
A UDP (SOCK_DGRAM) socket, on the other hand, can sendto() a message to a broadcast IP (if you enable the socket's SO_BROADCAST option beforehand), and it can recvfrom() a message that was sent to a broadcast IP belonging to the adapter that the socket is bound to.
Just note that bind()'ing a broadcasting UDP socket to 127.0.0.1 means that only UDP receivers also bound to 127.0.0.1 will be able to receive the broadcasts. You won't be able to broadcast over the network.
import socket
client_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#client_server.bind(("127.0.0.1", 12345))
client_server.setsockopt(client_server.SOL_SOCKET, client_server.SO_BROADCAST, 1)
client_server.sendto("New user is connected".encode("utf-8"), (f"{socket.INADDR_BROADCAST}", 12345))

Related

How can I use python sockets over the internet

I'm building a simple chat app using python and want to use it over the internet. The server is starting on my local machine which has the port already forwarded, and to allow other users to access I provided them with the IP address I got from www.whatismyip.com. However, every time I test the application the client side gets this error :
client_socket.connect((ip,port))
TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not
properly respond after a period of time, or established connection failed because connected host has
failed to respond
The server side is like this :
import socket
shost = socket.gethostname()
ip = socket.gethostbyname(shost)
port = 5000
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((ip,port))
server_socket.listen()
print(f"Server started on {ip}:{port}")
...
And the client side :
import socket
ip = "41.102.XXX.XX"
port = 5000
username = input("Username : ").encode('utf-8')
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((ip,port))
client_socket.send(username)
...
If you are behind a router/NAT, and the PC where your server is has a LAN IP address, then you have to configure port forwarding in the router/NAT from port 5000 to port 5000 in the local IP address.
Other 2 possibilities: 1) the client is not sending the packets to the correct IP address, maybe not through the correct network interface. To check this you can use wireshark in the client machine. 2) there is some firewall rule in the server dropping the incoming messages. This is possible if you're getting the error after more than one minute. This usually happens when after the TCP SYN message there is no TCP SYN/ACK message. And not seeing the SYN/ACK is because the SYN message doesn't get to the server's listening port.

python 2.7 Client Server UDP communication, how to overcome packet loss?

I have a UDP communication between a server and client on localhost
according to this code:
https://pymotw.com/2/socket/udp.html
Echo Server:
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('127.0.0.1', 12321)
sock.bind(server_address)
while True:
data, address = sock.recvfrom(4096)
if data:
sent = sock.sendto(data, address)
echo Client
import socket
import sys
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('127.0.0.1', 12321)
message = 'This is the message. It will be repeated.'
try:
for i in range 4:
sent = sock.sendto(message, server_address)
data, server = sock.recvfrom(4096)
finally:
sock.close()
now let's say I got some MITM attack, and a specific packet doesn't arrive at the server, and the client is still waiting for a response from the server,
I get a deadlock.
how can I overcome this? is there some timeout parameter for UDP socket?
Yes, there is a timeout for UDP sockets. See socket.settimeout() in https://docs.python.org/2/library/socket.html and read up on non-blocking sockets in general.
Note that UDP packets can be dropped, duplicated, and/or re-ordered, even if there is no man-in-the-middle attacker. This is because UDP is (by design) an unreliable datagram protocol.
If you need a reliable protocol use TCP (or QUIC).
If you need assurance that no man-in-the-middle can modify or (optionally) observe the data, use TLS (or QUIC).

Python - How to get port of sender socket (UDP)

If I have a UDP socket like so:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
and the socket can send data:
sock.sendto("message", address)
How do I find out the port of the socket - the port used when sending data to address?
EDIT: I tried sock.getsockname() but this raises an error: [Errno 10022] An invalid argument was supplied
I'm not too familiar with the python socket class, but based on what I've read here https://docs.python.org/2/library/socket.html#socket.getnameinfo
perhaps
socket.getnameinfo()[1] might work
since .getsockname() returns a 2-tuple (host, port)
The socket must be bound before you can use .getsockname() by doing sock.bind(('', 0)).
Hope this helps!

python socket connecting to different subnet/domain

Is it possible to connect to a different subnet or domain by python socket programming?
I want to make a script for sharing files with friends,, but currently I only know how to
connect within one LAN.
in LAN, you should broadcast packets to discover each other.
and every peer should listen the port to receive broadcast.
It is discovery protocol, you can implement it by UDP socket.
Once two peer decide to communicate, they should create a TCP socket. Then, they can send data via TCP.
Or you can use HTTP, XML-RPC etc. to transfer data(not broadcast, TCP is not support broadcast).
#udp broadcast
import socket, time
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
while True:
data = 'test'.encode()
s.sendto(data, ('255.255.255.255', 1080))
time.sleep(1)
#udp receive broadcast
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('', 1080))
while True:
print(s.recv(1024))

TCP Sockets defined as tuples and python

If a TCP socket is defined by a 4-tuple (source IP,source port,destination IP,destination port), then what would be the values for a TCP socket created in Python after the following Python code has been executed (i.e. when a server application is set to 'listen' to this socket)?
from socket import *
serverPort = 12000
serverSocket = socket(AF_INET,SOCK_STREAM)
serverSocket.bind((‘’,serverPort))
serverSocket.listen(1)
print ‘The server is ready to receive’
In particular, what does Python set for the destination values of a socket that a server is listening to?
Are these values randomly set, and if so how can I view them once a socket has been created?
The above code and question is taken from, and relates to, Kurose-Ross-Computer Networking.
Thanks in advance.
To query the source and destination addresses of a socket, call the getsockname() and getpeername() methods on the socket object.
In your case, serverSocket.getsockname() returns ('0.0.0.0', 12000) because that is the bind address you specified. getpeername() on a server socket always raises a socket.error: Transport endpoint is not connected because the server socket cannot be connected to a remote peer.
For a server socket to accept incoming connections, you must call its accept() method. This will return a client socket for which the peer name will be the pair of (address, port), address being the IP address of the peer, and port being the local port number assigned for communication with the peer.
If a TCP socket is defined by a 4-tuple (source IP,source port,destination IP,destination port)
It isn't. A TCP connection is so defined. A TCP socket is just an endpoint.
then what would be the values for a TCP socket created in Python after the following Python code has been executed (i.e. when a server application is set to 'listen' to this socket)?
It would have a local port of serverPort, a local address of 0.0.0.0, and no remote address or port.

Categories

Resources