didn't recv UDP dgram socket - python

So. There is a server and a client. The client knows the address of the server based on UDP dgram and sends packets to the server. But strange thing. Packets seem to be leaving, but the server does not read them. That is, in the recv block, he does not see messages until a mutual packet is sent back to the client (knowing his address in advance). And only then he starts to see messages from the client. Tell me please, what is the problem? (I don't use broadcastcasts, because both the server and the client are at a distance).
Code example:
import stun
import socket
import threading
source_ip = "0.0.0.0"
source_port = 9992
external_ip = None
external_port = None
sock = None
def GetIP(ip, port):
global external_ip, external_port, sock
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((ip, port))
sock.settimeout(0.1)
nat_type, nat = stun.get_nat_type(sock, ip, port, stun_host='stun.l.google.com', stun_port=19302)
if nat['ExternalIP']:
external_ip = nat['ExternalIP']
external_port = nat['ExternalPort']
print("my addr: %s:%s\n" % (external_ip, external_port))
sock.shutdown(1)
sock.close()
return ip, port
else:
port += 1
return GetIP(ip, port)
source_ip, source_port = GetIP(source_ip, source_port)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((source_ip, source_port))
data = None
remote_ip, remote_port = input(
"input `addr:port` other machine >"
).split(':')
remote_port = int(remote_port)
remote = remote_ip, remote_port
def read_chat(s):
global data
while True:
try:
data, addr = s.recvfrom(1024)
print(addr,'>', data)
except TimeoutError:
continue
reader = threading.Thread(target=read_chat, args=[sock])
reader.start()
while True:
line = input(">")
if ':' in line:
remote_ip, remote_port = input(
"input `addr:port` other machine >"
).split(':')
remote_port = int(remote_port)
remote = remote_ip, remote_port
else:
sock.sendto(line.encode(), remote)
Two such instances are started from the same network. also launched two different instances from different networks and then from the same network. Windows system firewall is disabled.
tried different combinations of sockets.

Related

UDP socket not receiving data from peer in python

I have a p2p simple chat app in python. A server code receives the IP and port of peers and sends each peer address to another:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', 44444))
while True:
clients = []
while True:
data, address = sock.recvfrom(128)
clients.append(address)
sock.sendto(b'ready', address)
if len(clients) == 2:
break
c1 = clients.pop()
c2 = clients.pop()
try:
sock.sendto('{} {} {}'.format(c1[0], c1[1], c2[1]).encode(), c2)
sock.sendto('{} {} {}'.format(c2[0], c2[1], c1[1]).encode(), c1)
except Exception as e:
print(str(e))
In my client code, first I start sending client info to the server (This part works properly):
import socket
import threading
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.bind(('', 40270))
sock.sendto(b'0', ('X.X.X.X', 44444))
while True:
data = sock.recv(1024).decode()
if data.strip() == 'ready':
break
ip, myport, dport = sock.recv(1024).decode().split(' ')
myport = int(myport)
dport = int(dport)
print('\n ip: {} , myport: {} , dest: {}'.format(ip, myport, sport))
This part of the code starts listening to the server after sending the current client's info to the server and when the other client gets connected, it receives its IP and port.
After connecting two clients and exchanging their addresses, a p2p connection is established between them.
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.bind(('', myport))
sock.sendto(b'0', (ip, dport))
print('ready to exchange messages\n')
Then, I run a thread to start listening to the other client like this:
def listen():
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', myport))
while True:
data = s.recv(1024)
print('\rpeer: {}\n> '.format(data.decode()), end='')
listener = threading.Thread(target=listen, daemon=True)
listener.start()
Also, another socket is responsible to send messages:
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', myport))
while True:
msg = input('> ')
s.sendto(msg.encode(), (ip, dport))
After all, as I said before, the server exchange the IP and port of clients properly. But messages were not received by another client after sending.
I think the problem is about the wrong port choice while I do the exchange.
Regards.
It is completely functional on Linux. The problem just occurred on a windows machine.

How to protect data transmitted by socket?

This code is for sending and receiving between my PC and AWS Instance
I want to know whether the transmitted data is considered secure? or do I need something else to ensure the security of the transmitted data?
If the data is not encrypted, what is the addition to the code to make it secure?
code's client
import socket
HOST = "public ip of server"
PORT = 4444 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(b"Hello, world")
data = s.recv(1024)
print(f"Received {data!r}")
server's code
server code
import socket
HOST = "0.0.0.0"
PORT = 4444 #open this in your router
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print(f"Connected by {addr}")
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)

ConnectionRefusedError when trying to host python socket server on raspberry pi

I'm trying to make a basic python networking program. All I'm trying to do is send strings of text back and forth between the server and the client. I'm trying to host the server on my Raspberry Pi, and connect with a client on Windows 10. The program works great locally on my computer, but when I try to connect to my server, it gives me ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it. My server code is as follows:
import socket # Import socket module
import netifaces as ni
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.
s.bind((host, port))
#host_ip = ni.ifaddresses('wlan0')[ni.AF_INET][0]['addr']
host_ip = "bruh?"
print("Server started! \nHostname: " + host + " \nIP: " + host_ip + " \nPort: " + str(port))
s.listen() # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print('Got connection from', addr)
output = "Welcome to the server!".encode()
c.send(output)
c.close()
Client code:
import socket
s = socket.socket()
host = 192.168.1.21
port = 12345
s.connect((host, int(port)))
noResponse = False
serverResponse = s.recv(1024).decode()
print(serverResponse)
s.close()
Does anyone know what my problem is? Thanks.
There may be a few reasons you are getting a ConnectionRefusedError, please try the following:
Check that no firewall is blocking your connection.
Double-check the server IP, if it is wrong you may get this error.
Try to use Hercules to check the connection.
Also, I would change the code as follow:
Server:
import socket
HOST = '' # localhost
PORT = # IMPORTANT !! Do not use reserved ports
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.bind((HOST, PORT))
sock.listen()
conn, addr = sock.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data:
break
print('Data: ',data)
conn.sendall('RT')
Client:
import socket
HOST = '' # server IP address
PORT = # server port
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((HOST, PORT))
sock.sendall('Hello, I am the Client')
data = sock.recv(1024)
print('Received', data)
By doing this you are using a TCP connection and you can test your code with different TCP server and client emulators.

Socket Error : No connection could be made because targeted machine actively refused it

Note : This problem has been completely solved, as was am running client.py before server.py
Just got started with socket programming, I have created the below code and expecting to print some byte message, but it isn't doing that.
I just want to make the message available for any person on any
machine. But it's refusing by the machine to do that.
Here is my code:
server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 12048
s.bind((socket.gethostname(), port))
s.listen()
while True:
c, addr = s.accept()
print("Got connection from", addr)
c.send(bytes("Thank you", "utf-8"))
client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 12048
s.connect(('192.168.0.1', port))
msg = s.recv(1024)
print(msg.decode("utf-8"))
Some images to better explain my errors:
Any help would be appreciated!!!
It looks like in the server.py script you use s.bind((socket.gethostname(), port)) where socket.gethostname() is a hostname, but in the client.py script you use s.connect(('192.168.0.1', port)) where '192.168.0.1' is the hostname you are trying to connect.
I think there you have socket.gethostname() != '192.168.0.1' and that's the problem.
Also, you can bind to all available IP addresses on the host using this solution Python socket bind to any IP?
Let's use listen_ip = socket.gethostbyname(socket.gethostname()) for connection since socket.gethostname() may return hostname instead of IP and it will not be solved by python dns resolver in local network if it was local name, not DNS.
and use it later as s.bind((listen_ip, port)) and s.connect((listen_ip, port))
After some debugging I've got a working solution for you
There are the scripts required.
server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostbyname(socket.gethostname())
port = 12_048
s.bind((host, port))
s.listen()
print("Server listening # {}:{}".format(host, port))
while True:
c, addr = s.accept()
print("Got connection from", addr)
c.send(bytes("Thank you", "utf-8"))
client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '192.168.1.162' # The IP printed by the server must be set here
# or we can set it using env variable named SERVER_IP
if 'SERVER_IP' in os.environ:
host = os.environ['SERVER_IP']
port = 12048
print("Connecting to {}:{}".format(host, port))
s.connect((host, port))
msg = s.recv(1024)
print(msg.decode("utf-8"))
In a chat conversation we concluded that the hardcoded IP in the question is not the correct one. This solution does have the IP he needed but it will be different in each case. Remeber that server.py needs to be launched first, and when you see the printed Server listening # IP:12048, write that IP in client.py and launch it. Client does need to be launched after seeing that line even if you already know the IP, as the server needs some time to be ready and the client will crash if it tries to connect to the server while it is not ready.
server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostbyname(socket.gethostname())
port = 12048
s.bind((host, port))
s.listen()
print("Server listening # {}:{}".format(host, port))
while True:
c, addr = s.accept()
print("Got connection from", addr)
c.send(bytes("Thank you", "utf-8"))
client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '192.168.1.162' # The IP printed by the server must be set here
port = 12048
print("Connecting to {}:{}".format(host, port))
s.connect((host, port))
msg = s.recv(1024)
print(msg.decode("utf-8"))

how to get Ip address of client after connection is established in python socket programming?

I wrote a socket program to send a file and receive a string from socket
In which I specified the client(wrote the ip address of client)
I want to get that client address dynamically,
I tried .getpeername() function but getting error
I tried .getpeername() function but getting error
#host = '10.66.227.181' # fixed ip of one client only
client_socket = socket.socket()
host = client_socket.getpeername()
print(clientip)
port = 8000
print(host,port)
client_socket.connect(host,port)
clientip = socket.gethostname(client_socket.getpeername())
OSError: [WinError 10057] A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
If a UDP socket isn't connected there is no peer. So there can't be a peer name.
And if it is connected, you already know how you connected it to.
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(host,port)
host, port = client_socket.getpeername()
Here is the example from the book 'Foundations of Python Network Programming' about udp sockets(both server and client side) and I think this example will be useful for you:
import argparse, socket
from datetime import datetime
MAX_BYTES = 65535
def server(port):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('127.0.0.1', port))
print('Listening at {}'.format(sock.getsockname()))
while True:
data, address = sock.recvfrom(MAX_BYTES)
text = data.decode('ascii')
print('The client at {} says {!r}'.format(address, text))
text = 'Your data was {} bytes long'.format(len(data))
data = text.encode('ascii')
sock.sendto(data, address)
def client(port):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
text = 'The time is {}'.format(datetime.now())
data = text.encode('ascii')
sock.sendto(data, ('127.0.0.1', port))
print('The OS assigned me the address {}'.format(sock.getsockname()))
data, address = sock.recvfrom(MAX_BYTES) # Danger! See Chapter 2
text = data.decode('ascii')
print('The server {} replied {!r}'.format(address, text))
if __name__ == '__main__':
choices = {'client': client, 'server': server}
parser = argparse.ArgumentParser(description='Send and receive UDP locally')
parser.add_argument('role', choices=choices, help='which role to play')
parser.add_argument('-p', metavar='PORT', type=int, default=1060,
help='UDP port (default 1060)')
args = parser.parse_args()
function = choices[args.role]
function(args.p)
source
The above answer is going to be confusing to most people due to the "host" terminology, so here's a better one:
ip_address = my_socket.getpeername()[0]
where my_socket is the handle to your socket you have already setup and connected.

Categories

Resources