2

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.

8
  • Do a test with your firewall completely unactivated. Commented Sep 20, 2013 at 15:29
  • Unfortunately disabling the firewall completely is not possible due to the group policy applied by my company's IT department. I could probably get this changed eventually, but given that I have a rule allowing access on all ports, and given that Apache is visible when run on the same port, I can't see how the firewall can be the problem. Commented Sep 20, 2013 at 15:37
  • 1
    Simple debug step would be to open python and create a socket that's listening for a connection from anywhere. Then goto your remote machine, create a socket, and connect it to the listener. This is about as barebones as you can get. If you can't connect your remote machine, you have an external issue. 'import socket; s=socket.socket(); s.listen(1); remotesock, addr = s.accept()' Then on remote: 'import socket; s=socket.socket(); s.connect(serveraddr, serverport)' Commented Sep 20, 2013 at 15:44
  • 2
    Add python.exe to the firewall exception list. Commented Sep 20, 2013 at 15:45
  • 1
    So, it appears that just having a firewall rule allowing traffic on all TCP ports wasn't enough. I needed to have a firewall rule allowing access to Python.exe (I'd done that earlier, but I'd ended up only allowing python.exe access to domain networks). Irritating. If someone wants to write that up as an answer, I'll upvote it to give them karma. :-) Commented Sep 20, 2013 at 16:26

1 Answer 1

1

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() 
Sign up to request clarification or add additional context in comments.

2 Comments

I see the same behaviour if I use the IP address, '0.0.0.0 or if I use an empty string.
@drz it helped me a lot for some other scenario. thanks a lot!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.