Python2 socket.recvfrom() / recv() differences between LInux and Windows? - python-3.x

I can successfully receive packets in Ubuntu 20.04 by calling bind() and receiving a message with recvfrom(). However, switching to Windows seems to have broken that. After clearing up a firewall issue, I can successfully receive the packet in Python 3.9, but I still cannot receive it in Python 2.7 (which is what my current program is using). When running in Python 2.7, it seems to get hung up on the recv() / recvfrom() call until I terminate it. 2.7 and 3.9 work fine in Ubuntu, so I seem to only be having this issue with Python 2.7 on Windows.
UPDATE: I did not think the IP address and port were important, as the code runs perfectly fine on Ubuntu and Windows using Python 3. I do not have access to the server-side of the code yet but will hopefully update later. What I do know is that the board is broadcasting to the particular port and IP address I have bound to below.
recv_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
recv_socket.bind(("192.168.11.149", 5155))
data = recv_socket.recv(1024)
print(data)
I am connecting to the particular IP intentionally, instead of accepting all IP addresses. That IP is also the correct one shown in ifconfig/ipconfig on my Ubuntu and Windows OS (on the same machine) since I am hardwired to our board through that particular port.
Is there a change in behavior between Windows and Ubuntu that I am missing? Or a change between Python 2.7 and Python 3.9 that would cause the recv() call to freeze up like this?

No change, but giving an actual example of client and server code that breaks would go a long way to getting an answer as to the behavior you see.
Here's code that works in Python 2 and Python 3. The client and server do not have to be the same version of Python.
server.py
from __future__ import print_function
import socket
recv_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
recv_socket.bind(('',9999))
while True:
data,addr = recv_socket.recvfrom(1024)
print(addr,'->',repr(data))
client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(b'hello',('localhost',9999))

Related

python tcp socket has delay on the first message on linux vps

Honestly, I am new in python tcp sockets and I wrote a simple code for the server side.
When I run the code locally, everything is fine and I receive the message from the local server immediately, but when I put the code on a vps (linux) and run the code with python3 test.py and send a message from client to the server, server receive the message from client and waits about 1 minute to send the message back to the client and after that everything is fine and the messages transfer between server and client without any delay. I tested other platforms such as nodejs, other vps and also setting ssl for the vps and using non-blocking mode and changed the recv() buffer size too but I faced the same thing.
I used telnet and a client with python and also faced the same issue.
I will be so thankful if you help me out with this.
Best regards
client (also telnet)
import socket
c = socket.socket()
c.connect(('my_ip',56112))
c.send(bytes("1",'utf-8'))
c.recv(1024).decode()
c.close()
server
import socket
s=socket.socket()
print("socket created!")
s.bind(('0.0.0.0',56112))
s.listen(3)
print("waiting for connections!")
while True:
c, addr = s.accept()
name = c.recv(1024).decode()
print("connected with",addr,name)
c.send(bytes("hi there",'utf-8'))
c.close()
could you help me to solve this?

Cannot create firewall or ACL in Python 3.11 on linux

I have to create simple python firewall or at least extended access control list like on Cisco program running on kali linux with newest python version.
I already have python sniffer using socket and struck and that works. Now i just need the program to decide when forward a packet if it follows some rules like source IP address or source port. In my sniffer i already extracted the ethernet, IP, TCP, UDP headers so i am able to make the decision for ACL based on it's fields successfully. Now i just need the program to drop and not forward it when decided.
I tried netfilterqueue, iptables, netfilter libraries but that doesn't seem to be working with python 3.11 and i'm worried that downgrade will disrupt my currently working sniffer. So is there a way to code a firewall or ACL with python 3.11 or 3.10 ?
This is a part of code i use to capture packet for deep inspection but then i have to extend it with firewall rules for forwarding decisions. Is there a chance to do it using socket. The if statement is an example of what i'm trying to achieve and that's force the program to drop the packet.
import socket
import struct
forbidden_ip = 192.168.1.5
interface = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0800)) # Linux
while True:
packet = interface.recvfrom(65565)
ip_header = struct.unpack("!BBHHHBBH4s4s", (packet[0][14:34]))
srcip = socket.inet_ntoa(ip_header[8])
dstip = socket.inet_ntoa(ip_header[9])
if srcip == forbidden_ip:
# now i need to drop the packet. iptables and netfilterqueue does not work for python 3.10 and 11
else:
continue

How to send a message between 2 computers

I have looked into many tutorials and source code for pythons socket modal to try to send a simple string between two computers.
I have made my code work independently on the PCs, but have failed to get the code to run on both. Here is the code I am currently working with:
#server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1234))
s.listen(5)
while True:
# now our endpoint knows about the OTHER endpoint.
clientsocket, address = s.accept()
print(f"Connection from {address} has been established.")
clientsocket.send(bytes("Send test","utf-8"))
clientsocket.close()
#client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1234))
while True:
full_msg = ''
while True:
msg = s.recv(8)
if len(msg) <= 0:
break
full_msg += msg.decode("utf-8")
if len(full_msg) > 0:
print(full_msg)
I am running the client script on both computers, but when I run the script on the pc not running the server, I get error the connection refused error [#10061]. I am running python 3.7, one pc is a laptop connected via internet, and one is a desktop connected to a router via Ethernet cable.
If someone knows what I need to change to get the program to run correctly, it would be much appreciated.
I am a rookie in python but I have experience in networking. Your problem sounds like a network issue to me. Before you run your program, you have to make sure there is connectivity between the two computers as you mentioned a laptop in the internet. Best way to know is pinging to each other. Your problem sounds like a typical NAT (network address translation issue).
I think you didn't open your '1234' port in your firewall.
https://www.windowscentral.com/how-open-port-windows-firewall
If you are using windows, this link can help you

Using socket module in website integrated python 3 IDE

import socket
a = socket.gethostbyname(socket.gethostname())
print(a)
When I run this code in the IDE in my pc, it shows the Ipv4 address of my pc.
But when I run this code in the integrated IDE in sololearn, it shows some other Ipv4 address but not mine. How to modify the code to show the Ip address of the user and not the server?
socket.gethostname()
Return a string containing the hostname of the machine where the
Python interpreter is currently executing.
Note: gethostname() doesn’t always return the fully qualified domain
name; use getfqdn() for that.
I've never heard of sololearn, but the python documentation is crystal clear on this one. It's possible your local name resolver is configured strangely, but that is beyond the scope of this question.

How to redirect commands to a raspberry from an android App?

I have a trial version of a VPS, I want to use this as a server to send commands from a smartphone to the raspberry.
I am using http to send requests to the VPS but how can I redirect the commands received from the smartphone to the raspberry?
You can code a client-side script in Python which reads the response from the VPS each 2 seconds (or other time) and execute the command you want. E.g.
client-side script (read.py)
#client example
import socket, time
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('theVPSip', 80)) # port 80 by default
TIME = 2 # amount of time to wait. Do not saturate VPS server
while 1:
time.sleep(TIME)
data = client_socket.recv(512)
print "RECIEVED:" , data
import subprocess
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output = process.communicate()[0]
server-side script
Depending on what language you code, you will use a different syntax (of course). But I'll tell you what you have to do:
Register the Raspberry IP into a variable (only first time, experimenting, then let it fixed)
Register to-be-sent commands in a database
Check if the request comes from the RPi or from the phone.
RPi-> send command to execute as a return in plain text
Phone-> register data (taken from POST/GET request) into database
I suppose you could communicate with the raspberry using other model, but you would need to have a bigger control to the server and be able to run scripts of the kind of a socket connection (e.g. using Python/Java)

Resources