python ThreadedTCPServer can only access local connections on windows 7 - python

I'm using ThreadedTCPServer to start a TCP server. Here is the code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import threading
import SocketServer
import time
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
recv1 = self.request.recv(1)
print "server: %s" % recv1
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
if __name__ == "__main__":
server = ThreadedTCPServer(('0.0.0.0', 8080), ThreadedTCPRequestHandler)
print server.server_address
# Start a thread with the server -- that thread will then start one
# more thread for each request
server_thread = threading.Thread(target=server.serve_forever)
# Exit the server thread when the main thread terminates
server_thread.daemon = True
server_thread.start()
print "Server loop running in thread:", server_thread.name
time.sleep(30)
server.shutdown()
print "end"
I'm working on Windows7(IP: 192.168.1.180)/Python2.7, when starting the program, I can telnet the server from local, but from another machine, I can't telnet success.
> telnet 192.168.1.180 8080
But, I run the program on Linux, it works fine. I can telnet it successfully from another machine.
Why on Windows7 it can not receive remote connection? I checked the net status on windows7 during running:
C:\Users\Henry>netstat -ant | findstr 8080
TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING InHost
Sorry, problem solved. It IS a environment problem. It's blocked by the windows7 firewall.

Your program does seem to be listening for connections correctly. And looking at this post from the superuser's stack exchange, it appears that your configuration is correct. See:
https://superuser.com/questions/386436/the-meaning-of-port-0-in-netstat-output
If your script works in one place but not another, I would look at the environmental differences. Since your client can't connect to the server, I would guess you got some kind of a connection refused error.
Is your windows firewall (or some other third party firewall) blocking inbound connections on port 8080? That seems likely since it is a port commonly used by web servers.

Related

How to close all active connections to `TCPServer` in Python?

I have a simple TCP server. There is an issue that occurs when I connect to the server using the Google Chrome browser: after a request, it seems to open another socket to send the next request there quickly next time. When such a socket is opened, I cannot restart my server gracefully. I can use the allow_reuse_address hack but it is not the thing I want to do because the port is still busy after the server shutdown, and if I wish another server to listen to this port, it is unable to do this.
I am sure there may be other cases when I don't want my port to be held by a nasty client and I would like to have the ability to force disconnect it. If I force to disconnect the server and then try to connect again, I get
OSError: [Errno 98] Address already in use
Here is an example. Let us imagine some "dirty client" connecting to my server and doing nothing (simply to consume the resources of my server). I want to shut down my server (let us say, for maintenance). I cannot do this until the client disconnects. I wish to disconnect it manually from the server-side.
from http.server import BaseHTTPRequestHandler
from socket import socket, AF_INET, SOCK_STREAM
from socketserver import TCPServer
from threading import Thread
from time import sleep, time
def dirty_client():
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect(("127.0.0.1", 8080))
sleep(10)
client_socket.close()
if __name__ == "__main__":
# Spawn TCP server
server = TCPServer(("127.0.0.1", 8080), BaseHTTPRequestHandler)
thread = Thread(target=server.serve_forever)
thread.start()
# Block it with a connection (should be on client side)
hang_thread = Thread(target=dirty_client)
hang_thread.start()
sleep(1)
# Let it hang
start = time()
print("Shutting down...")
server.shutdown()
server.server_close()
print(f"Success in {time() - start} seconds")
thread.join()
hang_thread.join()
The server hangs on the moment the request handler reads the socket. There is no timeout for reading and I cannot close the file during the read. The server itself can be shut down during the read, but the port will not be freed in this case.
It is possible to use BaseRequestHandler in this example — after it, the port is also in use. Though, BaseHTTPRequestHandler waits until the port is freed.

Stop SimpleHttpSever in jupyter notebook

I am using SimpleHTTPServer in jupyter notebook like this:
import SimpleHTTPServer
import SocketServer
PORT = 8000
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
It works good, but how can I stop it later in next input block?
The answer is that you can't.
You're unable to reference previous cells (or the results of) inside of Jupyter Notebook - see this open issue for more details on the discussion.
This means you can't manipulate the object once you've used the serve_forever() function.
It may however be possible to rewrite serve_forever to fit your needs. Currently it will literally serve no matter what but adding a condition that allows you to connect and issue a 'shutdown' command would circumvent the need to call up the object later. You could just connect to the socket and issue a customised header that the TCP server would pick up and respond to.
As a quick example to start you on this path:
class StoppableRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):
def serve_forever(self):
while not self.stopped:
self.handle_request()
def not_forever(self):
# Called from another function when a custom header is detected
self.stopped = True
self.server_close()
the server are running in background you need to search the PID an kill it like:
netstat -tulpn
Netstat out:
tcp 0 0 0.0.0.0:8888 0.0.0.0:* LISTEN 12332/python
Kill PID with pkill or kill:
kill 12332

Problems running python program with srvany.exe

I must preface this with a full disclaimer that i'm very early in my python development days
I've made a simple python program that waits for a socket connection to the local ip address over port 20000. When it gets a connection, it pops up a message alert using the win32api.
#tcpintercomserver.py
import socket
import sys
import win32api
ip = socket.gethostbyname(socket.gethostname())
#socket creation
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#Binding
server_address = (ip, 20000)
sock.bind(server_address)
print server_address
#Listen
sock.listen(1)
while True:
# Wait for a connection
connection, client_address = sock.accept()
win32api.MessageBox(0,'MessageText','Titletext', 0x00001000)
# Close Connection
connection.close()
I also have a mated client program that simply connects to the socket. The script takes an argument of the host you're trying to reach (DNS name or ip address)
#tcpintercomcli.py
import socket
import sys
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect the socket to the port where the server is listening
server_address = (sys.argv[1], 20000)
sock.connect(server_address)
This all runs fine as scripts. I then used CX_Freeze to turn them into executables. Both run just like they did when they were scripts.
Now i've taken the server script and connected it to a service with srvany.exe and use of the SC command in windows.
I set up the service using SC create "intercom" binPath= "C:\dist\srvany.exe"
Under the intercom service key in the registry, i've added the Parameter's key, and under there set Application to a string value c:\dist\tcpintercomserver.exe
I then perform a "net start intercom" and the service launches successfully, and the tcpintercomserver.exe is listed as a running process. However, when i run the tcpintercomcli.py or tcpintercomcli.exe, no alert comes up.
I'm baffled...is there something with the CX_Freeze process that may be messing this up?
Service process cannot show messagebox, they don't have access to UI, they usually run as SYSTEM user. if you are running from service, proper way of debugging and showing messages are using EventLog.
See:
http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog%28VS.71%29.aspx
If you are on Windows Vista or later, your script is running headlong into Session 0 Isolation -- where GUI elements from a Windows service are not shown on an interactive user's desktop.
You will probably see your message box if you switch to session 0...

Closing socket after subprocess.Popen leaves socket in TIME_WAIT as long as child process is still running

On Windows 7:
Given this server code:
# in server.py
if __name__ == '__main__':
serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# uncommenting this won't help
#serversock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversock.bind(('',8888))
serversock.listen(5)
# accept and receive dummy data from client
clientsock,address = serversock.accept()
data = clientsock.recv(1024)
# as long as calc.exe is running, I can't do this again
subprocess.Popen(r"c:\windows\system32\calc.exe")
# letting client close first still won't help
time.sleep(3)
# closing won't help either
clientsock.close()
serversock.close()
And the client code
# in client.py
if __name__ == '__main__':
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 8888))
s.sendall('Hello, world')
# close early to help prevent TIME_WAIT on server, but doesn't help
s.close()
Running server first then client will launch the calculator app.
While the calculator app is still running, I can't run server again. It will complain about
python server.py (ok)
python client.py (ok)
python server.py (boom!)
socket.error: [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted
If I close the Calculator app, running server is ok again...
This does not happen on Mac.
Enabling SO_REUSEADDR will only make the error go away, but the server is unreachable from the client.
In the example above, I specifically let the client close first so that the server socket don't go into TIME_WAIT.
So the questions:
Am I running into the TIME_WAIT problem on the server?
Are any sockets/filedescriptors left unclosed in the server?
Why SO_REUSEADDR won't help in this case? could the client be coming from the same port?
Could the child process be hanging on to some descriptors?
What can I do about this?
The SOLUTION:
The problem IS with the parent process of Calculator holding on to some file descriptor.
So adding close_fds=True to the Popen will ensure everything is released properly.
subprocess.Popen(r"c:\windows\system32\calc.exe", close_fds=True)
Closing socket after subprocess.Popen leaves socket in TIME_WAIT as long as child process is still running
No it doesn't. It leaves it in TIME_WAIT for a fixed amount of time, 2 or 4 minutes. After the close it has nothing to do with the child process at all.

Using pexpect to listen on a port from a virtualbox

I am trying to create a tcplistener in python (using pexpect if necessary) to listen for tcp connection from Ubuntu in virtualbox on a windows xp host. I would really appreciate it, if one of you could point me in the right direction. Thank you.
P.S: I have limited experience in the area, any help would be welcome.
Python already has a simple socket server provided in the standard library, which is aptly named SocketServer. If all you want is a basic listener, check out this example straight from the documentation:
import SocketServer
class MyTCPHandler(SocketServer.BaseRequestHandler):
"""
The RequestHandler class for our server.
It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
"""
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print "%s wrote:" % self.client_address[0]
print self.data
# just send back the same data, but upper-cased
self.request.send(self.data.upper())
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()

Categories

Resources