Can't receive UDP broadcast in python - python

Here is broadcast server
from time import sleep
from socket import *
PORT = 50000
s = socket(AF_INET, SOCK_DGRAM)
s.bind(('', 0))
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
data = "I am server"
while 1:
s.sendto(data, ('<broadcast>', PORT))
print "sent data"
sleep(5)
Please note that you need to change '<broadcast>' with actual broadcast address of your network. Please see Python can't send a broadcast package with address
Here is broadcast receiver
from socket import socket, AF_INET, SOCK_DGRAM
PORT = 50000
client = socket(AF_INET, SOCK_DGRAM)
client.bind(('0.0.0.0', PORT))
data, addr = s.recvfrom(1024) #sticks here forever!
if data:
print "Found Broadcast server at : " + addr
But problem is that my receiver just sticks at s.recvfrom(1024)
While through tcpdump I am able to see the packet, then why this python client is not able to catch it ?
command is sudo tcpdump -i wlan0 ip -X dst host 255.255.255.255

I changed your code to Python 3 and corrected 2 errors:
Change s to client
Print the statement only when there is data from recvfrom()
Hope it helps.
from socket import socket, AF_INET, SOCK_DGRAM
PORT = 50000
client = socket(AF_INET, SOCK_DGRAM)
client.bind(('0.0.0.0', PORT))
while True:
data, addr = client.recvfrom(1024) #sticks here forever!
if data:
print("Found Broadcast server at : ", addr)

You need to set socket options before you bind it, and you need to bind it to INADDR_BROADCAST.

Related

Connect python local server with godot

I'm trying to send data to a python server:
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('127.0.0.1',6000))
s.listen(5)
while True:
clientsocket,address = s.accept()
print(f"Got connection from {address} !")
from godot:
var socket = PacketPeerUDP.new()
socket.set_dest_address("127.0.0.1",6000)
socket.put_packet("quit".to_ascii())
based on this link
but it doesn't seem to be working, How do I send the data?
i'm not that familiar with python servers, but it looks like you have a python server that listens for TCP connections but in godot you connect via UDP Client.
As seen in this Answer SOCK_STREAM is for TCP Server and SOCK_DGRAM for UDP.
I am not sure which of those you want to use. An example server for UDP would be:
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind(('127.0.0.1',6000))
bufferSize = 1024
#s.listen(5)
print("running")
while True:
bytesAddressPair = s.recvfrom(bufferSize)
message = bytesAddressPair[0]
clientMsg = "Message from Client:{}".format(message)
print(clientMsg)
I copied most of it from here : Sample UDP Server
If you wanted to have a TCP Server you should alter the Godot part to use a TCP Client. See the official docs here
figured it out thanks to #René Kling 's answer
just incase someone wants the complete version
python server:
import socket
HOST = "127.0.0.1"
PORT = 6000
s= socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind((HOST, PORT))
while True:
message, addr = s.recvfrom(1024)
print(f"Connected by {addr}")
Godot:
extends Node2D
tool
export(bool) var btn =false setget set_btn
var socket = PacketPeerUDP.new()
func set_btn(new_val):
socket.set_dest_address("127.0.0.1", 6000)
socket.put_packet("Time to stop".to_ascii())

How can i get three recieving messages from socket server instead two?

Hi guys i cant figure out why socket server sends me second message with the third one at the same time. However I want to get message one by one not together at the same time. How can i do this?
Server code:
import socket
host = socket.gethostbyname(socket.gethostname())
port = 5000
ADDR = (host, port)
s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
s.bind(ADDR)
s.listen()
c, addr = s.accept()
c.send(b'7:S ACK:4,')
c.send(b'11:S END:kSfdy,')
c.send(b'8:S 120794,')
Client code:
import socket
HOST = '192.168.1.54' # The server's hostname or IP address
PORT = 5000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
print(s.recv(1024))
print(s.recv(1024))
print(s.recv(1024)) #empty message

Unable to receive UDP broadcast packets client side using python

I have been trying to send broadcast message for a long time but unable to receive it at all from the other side and no error at all. Server side it quickly sends packet and client keeps listening but never prints. Please answer me if someone really did this. I am using two virtual machines of same linux ubuntu. One for server and other for client.
#client
from socket import *
s = socket(AF_INET, SOCK_DGRAM)
s.bind(("192.168.1.255",12345))
print s.recvfrom(4096)[0]
#server
from socket import *
s = socket(AF_INET, SOCK_DGRAM)
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
s.sendto("hi i am server!", ("<broadcast>", 12345))
I solved it myself.
Server side:
from socket import *
s = socket(AF_INET, SOCK_DGRAM)
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
s.sendto("hi i am server!", ("192.168.1.255", 12345))
Client side:
from socket import *
s = socket(AF_INET, SOCK_DGRAM)
s.bind(("192.168.1.255",12345))
print s.recvfrom(4096)[0]
Instead of using "<broadcast>" as an address we should use the same subnet address

Python Socket Error "Only one usage of each socket address is normally permitted"

I have a basic server and client that prints a message on the server when a client connects, and then prints a message on the client saying "Thanks for connecting." But when I try to run the server again(after closing it), I get "error: Only one usage of each socket address is normally permitted"(Not exact). And when I change the port again it works.
#Server
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
print 'Got connection from', addr
c.send('Thank you for connecting')
c.close()
.
#Client
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.connect((host, port))
print s.recv(1024)
s.close
If I change the last two lines of code for the server to
break
c.close()
it works but closes the server.
How can I keep the server up after the client disconnects without having to change the port each time?
You want to set the socket option SO_REUSEADDR:
Example:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

Python UDP Socket File Transfer

How do I get a response from the server?
Client side:
#CLIENT
import socket
import time
host = "localhost"
port = 5454
data_c = input()
c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
c.sendto(bytes(data_c, 'utf-8'),(host,port))
print( data_c )
print( c.recv(1024).decode('utf-8'))
SERVER side:
#SERVER
import socket
import time
host = "localhost"
port = 5454
data_s = "ACKNOWLEDGMENT"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
print(s.recv(1024).decode('utf-8'))
I can send a message from the server that the client will receive, but can not seem to get communication (like an ACK.) to make it back to the server.
(yes UDP is not a good way to be doing this i'm pretty sure, but that was a specific for the project)
for question 1: to send the ACK, you could replicate what you have in the reverse direction.
Since UDP is connection-less you don't know beforehand you receive a packet where the packet will come from, so you have to use recvfrom to get both the packet and the peer (address/port) the packet came from. Then you have to use that address to send data back.
What you're doing now in your client (but what really looks like the server) in the loop is send the same data over and over to itself. Instead in the loop you should receive packets using the previously mentions recvfrom then send replies to the peer you received the packet from.
So something like the following pseudo code
while True:
peer = recvfrom(...)
sendto(..., peer)
After many attempts to get a simple acknowledgment reply from my server this did it.
Beyond literally starting completely over each round, the time.sleep(.1) function was the only missing key. It allowed the server and client both time to close the current socket connection so that there was not an error of trying to bind multiple bodies to a single location or something.
OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted
Working result:
#SERVER
import socket
import time
host = "localhost"
port = 5454
data_s = "ACKNOWLEDGMENT"
while 1:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
received = print("Client: " + s.recv(1024).decode('utf-8')) #waiting to receive
s.close
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
time.sleep(.1)
s.sendto(bytes(data_s, 'utf-8'),(host,port)) #sending acknowledgment
print("Server: " + data_s)
s.close # close out so that nothing sketchy happens
time.sleep(.1) # the delay keeps the binding from happening to quickly
Server Command Window:
>>>
Client: hello
Server: ACKNOWLEDGMENT
Client:
#CLIENT
import socket
import time
host = "localhost"
port = 5454
c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while 1:
data_c = input("Client: ")
c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
c.sendto(bytes(data_c, 'utf-8'),(host,port)) #send message
c.close
# time.sleep()
c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
c.bind((host, port))
print("Server: " + c.recv(1024).decode('utf-8')) # waiting for acknowledgment
c.close
c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
time.sleep(.1)
Client Command Window:
>>>
Client: hello
Client: hello
Server: ACKNOWLEDGMENT
I did finally remove the redundant input("Client: ") there at the top.
A special thanks #JoachimPileborg for helping, but I have to give it to the little guy just because it was the path I ended up taking.

Categories

Resources