How can I get live established UDP connections with python using psutil - python

I am trying to get the destination IP (remote host) addresses connected to my machine that are using UDP protocol but i get Null results using psutil
the script I wrote
import psutil
def GetServerIP():
PROCNAME = "theprocessname.exe"
for proc in psutil.process_iter():
if proc.name() == PROCNAME:
pinfo = proc.as_dict(attrs=['pid', 'name', 'create_time'])
pidnumber = pinfo["pid"]
print("Process is runnging on number: %r" % (pidnumber))
for connection in psutil.net_connections(kind='udp4'):
if pidnumber in connection:
print(connection.raddr)
GetServerIP()
The script works for TCP connections but gives nothing on UDP connections that are established on my local machine.
I read through psutil documentation however still cant figure out why it gives no results back on UDP
I can verify there are established UDP packets being sent and received using wireshark
if psutil does not work well with UDP is there an alternative solution

It seems like psutil was not the right solution and path to take, turned out UDP connections are not established like TCP, so instead I switched to python scapy to capture UDP packets and it helped me resolve the destination IP address

Related

Python TCP Server blocks forever in send to client if client is stopped (SIGSTOP)

I have an extremely simple tcp server in python the code for which is below:
#!/usr/bin/env python
import socket
sock = socket.socket()
sock.bind(('',3912))
sock.listen(100)
num_cons = 10
cons = []
for i in range(num_cons):
con, addr = sock.accept()
cons.append(con)
while True:
for con in cons:
msg = "a"* 1000
num_sent = con.send(msg.encode())
print("sent: {} bytes of msg:{}".format(str(num_sent), msg))
The corresponding client code is
#!/usr/bin/env python
import socket
sock = socket.socket()
sock.connect(('',3912)) # in reality here I use the IP of the host where
# I run the server since I launch the clients on a different host
while True:
data = sock.recv(1000)
print("received data: {} ".format(str(data)))
Now, if I start the server with
./server.py
and 10 clients in parallel from a different host:
for i in `seq 1 10`; do ./client.py 2>/dev/null 1>/dev/null & done
And I send kill -SIGSTOP %1 to the first client, I expect the server to successfully keep trying to send data because it cannot know that the client has been stopped. Instead, the server blocks when it tries to send the data to client 1. I can understand the behaviour if the clients were on the same host as the server: we tried to write data, but the kernel buffers are full, so we block in the server, but the client never reads, so the buffer is never freed. However, if the clients are on a different machine, the kernel buffers of the server host should only be full temporarily and then the kernel should send the data over the network card and free them. So why is my server blocking on the send call? I have not verified if the same behaviour is seen when using a different language (C for example)
It is weird because 1000 characters is a small size for TCP. I have no available Linux machine but on a FreeBSD box, I could successfully send 130000 bytes on a TCP connection where the peer was stopped before the sender blocks. And more that 1000000 on Windows.
But as TCP is a connected protocol, a send call will block if it cannot queue its data because the internal TCP stack queue is full.
The gist of your problem seems to be that you're creating a SOCK_STREAM socket (i.e. TCP), and then abruptly terminating the client. As discussed in the Python Socket Programming HOWTO, a hang is expected in this situation.
TCP is a reliable protocol, meaning that every transmitted packet has to be acked. If the receiving side is dead, the sender will block waiting for that acknowledgement. Try setting a timeout and see if your send raises a socket.timeout after the expected time.

Can't connect to local Machine IP through TCP From Arduino Uno using SIM900 Shield

So you have a basic understanding of the parts im using, I have:
Arduino Uno
Seeed Studio GPRS Shield v2.0 (http://www.seeedstudio.com/wiki/GPRS_Shield_V2.0)
Ultimate GPS for Adafruit V3.3 (https://www.adafruit.com/products/746?gclid=Cj0KEQjw3-W5BRCymr_7r7SFt8cBEiQAsLtM8qn4SCfVWIvAwW-x9Mu-FLeB6hLmVd0PAPVU8IAXXPgaAtaC8P8HAQ)
Here is my problem:
I have tested the Arduino stacked with the GPRS shield, and it works fine with regards to accessing the internet through TCP, sending SMS, etc.. However, my application requires me to send GPS data from the adafruit GPS to a web server that I have already coded with Django and postgresql. The backend is set up.
I need to send the data from the Uno (client) to my laptop (server), which I coded in python (This is just to check whether it is creating a connection):
#!/usr/bin/env python
import socket
# import postgres database functions
TCP_IP = '192.168.1.112'
TCP_PORT = 10000
BUFFER_SIZE = 40
server_address = (TCP_IP,TCP_PORT)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created.'
# Bind socket to TCP server and port
try:
s.bind(server_address)
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket Bind Complete.'
# Start Listening on socket
s.listen(1) # Puts socket into server mode
print 'Listening on port: ', TCP_PORT
# Now Keep Talking with the client
while (1):
# Wait to accept a connection
conn, addr = s.accept() # Wait for incoming connection with accept()
print 'Connection address:', addr
data = conn.recv(BUFFER_SIZE)
if not data: break
print "recieved data: data", data
conn.send(data) #echo
conn.close()
I dont think there is a problem with this. From this I will post data to my postgreSQL database. However, When I try to use AT commands on the SIM900 module to connect to the server using port 10000, I cannot connect:
AT+CIPSHUT
SHUT OK
AT+CGATT?
+CGATT: 1
OK
AT+CIPMUX=0
OK
AT+CSTT="fast.t-mobile.com","",""
OK
AT+CIICR
OK
AT+CIFSR
6.60.94.49
AT+CIPSTART="TCP","192.168.1.112,"10000"
OK
STATE: TCP CLOSED
CONNECT FAIL
I have tried connecting through TCP and replaced the AT+CIPSTART line with the below statement and it worked, so I know TCP works:
AT+CIPSTART="TCP","www.vishnusharma.com", "80"
Is the IP i'm using wrong? I'm new to this, but if it makes a difference, im using Ubuntu 16.04 partitioned on my Mac OSX. I have also checked the APN for T-mobile and it seems fine.
Any help would be greatly appreciated. Thank You!
The IP you're using is inside a NAT since it starts with 192.168. Unless you have a private apn with the mobile operator you're using, you won't be able to reach your Ubuntu from a public IP. Your ISP gives you a public IP address which ir administrated by your router, so if you want this to work, you'll have to do a port forwarding from your router to your Ubuntu.
To do the port forwarding you have to get in the router's configuration page (Typically 192.168.1.1 but depends on the model) an there you'll have to redirect the port XXX to 192.168.1.112:10000. After that you have to obtain your public IP (curl ifconfig.co) and use it to access from the SIM900.
First of all as a suggestion, you can combine the two shields by using SIM908 (unless you are getting more precision on your GPS shield). Since your TCP connection is working, I bet that the port 10000 on your ubuntu is blocked by the firewall. You can first try to turn off your firewall and see if it works. If it did not worked its something else. If it worked, turn on your firewall and then unblock the tcp port using the following command:
sudo ufw allow 10000/tcp

Python alternative to linux bluetooth command "rfcomm connect"

Requirement:
I need to connect to a remote bluetooth device & port and send data using a device file.
1. First scan the nearest bluetooth devices
2. connect to a remote BT addr & channel and communicate using a device file (/dev/rfcomm0)
I'm stuck at the second step. I'm able to do it through linux shell
sudo rfcomm connect /dev/rfcomm0 00:11:22:33:44:55 1 &
This works and then I open my python interpreter and communicate to the remote device using the rfcomm0 device file.
But my requirement is such that the device addr could be changing. So I want to connect and release the connections through python program.
I tried using python subprocess.
But the problem is it returns immediately with a returncode 0 and then the connection is established after certain latency.
import subprocess
host = '00:11:22:33:44:55'
port = "1"
subprocess.call(["rfcomm connect",host,port,"&"],shell=True)
I'm looking if there is any pyBluez or any other python alternative to achieve this.
import subprocess
host = input()
port = 1
cmd = "sudo rfcomm connect /dev/rfcomm0 {} {} &".format(host, port)
conn = subprocess.Popen(cmd, shell=True)
if conn.returncode is None:
print("error in opening connection")
import the subprocess module
Read bluetooth address from the user(host)
port number can also be read as input, I am considering the default port 1
cmd = "sudo rfcomm connect /dev/rfcomm0 {} {} &".format(host, port) will create a command from the given arguments
There are many ways to read the output and errors after the execution of command. Read more about Popen#https://docs.python.org/3/library/subprocess.html
You can you the os module to run Shell commands. You can store the return value like this:
from os import system
Returnedstring = system("Shell command")

Python socket on Windows 7 is not accessible from another machine

I'm trying to create a Python program that will listen on a socket. I'm using Windows 7 with Python 2.7. Whatever I do, the socket seems to be accessible from the local machine but not from elsewhere on the network.
I've got the following code:
from werkzeug.wrappers import Request, Response
#Request.application
def application(request):
return Response('Hello World!')
if __name__ == '__main__':
from werkzeug.serving import run_simple
# Using empty string or the machine's real IP address here
# gives the same problem
run_simple('0.0.0.0', 4000, application)
If I connect from the local machine I see the response fine. If I execute
$ curl 'http://192.168.1.1:4000/'
from another (linux) box on the network, the curl hangs for a long time before timing out. Wireshark shows that I receive a SYN packet to port 4000 but don't see it ACKed.
I've tried making sure packets to this port are allowed through the firewall (the fact that I see the SYNs in Wireshark suggests this is not the problem). I've tried setting Python to run as administrator (and I've checked that ctypes.windll.shell32.IsUserAnAdmin() returns true). This isn't just Werkzeug, I've tried with SocketServer from the Python standard library as well.
Running Windows Apache on the same port works fine from across the network, which suggests there's no problem with the network or firewall or with my curl request.
netstat -an shows:
TCP 0.0.0.0:4000 0.0.0.0:0 LISTENING
Edit: I've tried with the following minimal code. On the server side (Windows 7):
import socket
s = socket.socket()
s.bind(('', 8080))
s.listen(1)
remotesock, addr = s.accept()
And on the linux client:
import socket
s = socket.socket()
s.connect('192.168.1.1', 8080)
This hangs until timeout, as with the curl.
I believe the problem is due to your address binding. Python does not allow sockets bound to localhost (or 0.0.0.0) to be visible from the outside world. Change the binding to your actual IP Address.
EDIT: Showing example code
Change your code to this
import socket
s = socket.socket()
s.bind(('192.168.1.1', 8080)) # assumes your machine's IP address is 192.168.1.1
s.listen(1)
remotesock, addr = s.accept()

How to connect a Python socket on client-side to Node.js/socket.io?

I want to connect Blender (v2.55) to a webpage through sockets.
For the web part, I can use Node.js & socket.io. I've already used a little node.js/socket.io, it's not a problem I think.
Now for Blender, it runs on Python 3.1, so I've already sockets and I can add libraries if needed. I'm new to Python sockets, can I connect a client to node.js/socket.io directly ?
I tried with the basic code from the Python doc:
import socket
import sys
HOST, PORT = "127.0.0.1", 8080
data = "Hello from Blender"
# Create a socket (SOCK_STREAM means a TCP socket)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect to server and send data
sock.connect((HOST, PORT))
sock.send(bytes(data + "\n","utf8"))
# Receive data from the server and shut down
received = sock.recv(1024)
sock.close()
print("Sent: %s" % data)
print("Received: %s" % received)
It results by:
Sent: Hello from Blender
Received: b''
It seems that Blender is connected, but doesn't receive data. Also Node shows no new client connected…
Do I need something else ? If somebody can help me out…
You are missing a protocol/handshake. What you have there is a bare TCP socket connection. node.js/socket.io lives on top of a TCP socket. Basically when you open a connection to a socket.io server, it's expecting you to use some protocol for communication (websockets, longpolling, htmlfile, whatever). The initial handshake defines what that protocol will be. Websockets is one of the supported protocols. This blog post should help you. It doesn't look all that hard to get websockets implemented.
you can try the form of loop to receive valid data.
import socket
host="127.0.0.1"
port=8088
web=socket.socket()
web.bind((host,port))
web.listen(5)
print("recycle")
while True:
conn,addr=web.accept()
data=conn.recv(8)
print(data)
conn.sendall(b'HTTP/1.1 200 OK\r\n\r\nHello world')
conn.close()
and use your browser to visit the host and port for a check
I understand this thread is extremely old. But I faced the same problem recently and couldn't find an answer or any similar questions. So here is my answer.
Answer: Use socket.io for python python-socketio
The reason why built-in sockets or any other websocket library in python won't work is explained in the socket.io website socket.io
Socketio is simply just not a websoket connection. Although they say, it uses websockets for transport internally, the connection is established with HTTP protocol http:// as opposed to the WEBSOCKET protocol ws://. This results in the failure of handshake and the connection fails to be established.

Categories