I am trying to create applications that can communicate through sockets in python.I was already able to achieve this in a console program and was trying to do the same in WPF.It is quite a simple program that should act as the server,where a socket is created,bound to a port then listens for connections.The problem i am facing now is that everytime i include the code for the socket to accept a connection,my program hangs. I have tried to look for the solution online but everyone seems to be doing it exactly the same way i am doing it.Has anyone encountered this problem before and if so how did you solve it.
Thanks in advance for your help.
This is the code:
import wpf
import socket
import sys
import clr
import System
HOST=''
PORT = 8888
from System.Windows import Application, Window
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
class MyWindow(Window):
def __init__(self):
wpf.LoadComponent(self, 'managementToolSimulator2.xaml')
def Button1_Click(self, sender, e):
pass
def Window_Loaded(self, sender, e):
s.bind((HOST,PORT))
s.listen(5)
self.ListBox1.AddText('Listening...')
while 1:
conn,addr=s.accept()
self.ListBox1.AddText('Got connection')
pass
if __name__ == '__main__':
Application().Run(MyWindow())
If i run the program without the line:
while 1:
conn,addr=s.accept()
self.ListBox1.AddText('Got connection')
it runs fine but if i include the line the program hangs and has to be stopped from the task manager.
Thread off the server.
You must not make blocking calls in GUI event handlers. The GUI thread must handle Windows messages in a timely manner - you cannot just block execution in a handler.
Related
I am trying to create a sockets server (TCP/IP) and inside it based on few data from client I am scheduling few background jobs.
following code is working ->
import schedule
import time
def test1():
print('hi from 1')
def test2():
print('hi from test2')
while True:
schedule.run_pending()
time.sleep(1)
Then I tried following thing with socket server then its not executing the jobs/function. Can someone help me what's happening here.
Not working code
import schedule
import time
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 8009)
print('starting up on {} port {}'.format(*server_address))
sock.bind(server_address)
# Listen for incoming connections
sock.listen(1)
def test1():
print('hi from 1')
def test2():
print('hi from test2')
schedule.every(1).minutes.do(test1)
schedule.every(2).minutes.do(test2)
while True:
schedule.run_pending()
time.sleep(1)
print('waiting for a connection')
connection, client_address = sock.accept()
data = connection.recv(1024)
result = data.decode('utf-8')
print('data recived from clinet : ', result)
Thing I am trying to achieve is I want to create python socket server which
will accept request from node client's and based on clients data I want to schedule few jobs in python. for this I am using socket, schedule moduls from python to create socket server and schedule jobs respective and net module at node js's client for sending data to python server.
Please explain your problem in more detail. sock.accept is blocking, so the loop is blocking, is this your problem?
To prevent the program from blocking you can run the scheduler loop in a separate thread and the acceptance loop also in a separate thread too. Create a main thread to manage your child threads. Have a look at the module threading.
Maybe it makes sense to use an other scheduler library that can handle threading, see here.
Disclosure: I'm one of the authors of the scheduler library
How do you kill a websocket server programmatically? I'll be deploying this server to production along side other things. And I like to build a single python script that sends a kill signal to everything. I cannot figure out how to kill this thing without a user keyboard interrupt or a kill -9.
sys.exit() didn't work.
psutil and terminate() didn't work either
import os
import psutil
current_system_pid = os.getpid()
ThisSystem = psutil.Process(current_system_pid)
ThisSystem.terminate()
I'm out of ideas. For now I'm killing it on the command line with kill -9.
When I kill it varous ways, it tend to see this message below, but the scrip is still running
2020-12-12 12:24:54-0500 [autobahn.twisted.websocket.WebSocketServerFactory] (TCP Port 8080 Closed)
2020-12-12 12:24:54-0500 [-] Stopping factory <autobahn.twisted.websocket.WebSocketServerFactory object at 0x110680f28>
autobahn install:
pip install autobahn[twisted]
Code:
from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory
import sys
from twisted.python import log
from twisted.internet import reactor
class MyServerProtocol(WebSocketServerProtocol):
def onConnect(self, request):
print("Client connecting: {0}".format(request.peer))
def onOpen(self):
print("WebSocket connection open.")
def onMessage(self, payload, isBinary):
print("Text message received: {0}".format(payload.decode('utf8')))
# echo back message verbatim
# self.sendMessage(payload, isBinary)
def onClose(self, wasClean, code, reason):
print("WebSocket connection closed: {0}".format(reason))
def StopWebsocketServer():
PrintAndLog_FuncNameHeader("Begin")
reactor.stop()
PrintAndLog_FuncNameHeader("End")
if __name__ == '__main__':
# TODO remove the logging that came in the example
log.startLogging(sys.stdout)
factory = WebSocketServerFactory("ws://127.0.0.1:8080")
factory.protocol = MyServerProtocol
# note to self: if using putChild, the child must be bytes...
reactor.listenTCP(Port_ws, factory)
reactor.run()
Solution using #Jean-Paul Calderone's answer:
import os
import signal
os.kill(os.getpid(), signal.SIGKILL)
I have an external python script that sends a kill signal to each of my python scripts. The kill signal is simply the existence of a file that every script knows to look for. Once that kill signal appears, each script knows it has x seconds before it will be killed. This way they have a few seconds to gracefully finish something.
twisted.internet.reactor.stop() is how you cause the reactor to shut down. This is usually what results in a Twisted-based program exiting (though of course it doesn't necessarily have to, if the program does more things after the reactor shuts down - but this is uncommon).
However, it sounds like you don't want to know what Python code to run inside the process to end it. You want to know what some other process can do to your Twisted-based process to make it exit. You gave two solutions - KeyboardInterrupt and SIGKILL. You didn't mention why either of these two solutions is inappropriate. They seem fine to me.
If you're uncomfortable with SIGKILL (which you shouldn't be, after all, your program might meet an untimely demise for many reasons and you should be prepared to deal with this) then what you might have overlooked about KeyboardInterrupt is that it is merely the exception that is raised inside a Python program by the default SIGINT handler.
If you send SIGINT to a Twisted-based process then, under normal usage, this will stop the reactor and allow an orderly shutdown.
I'm implementing a bi-directional ping-pong demo app between an electron app and a python backend.
This is the code for the python part which causes the problems:
import sys
import zerorpc
import time
from multiprocessing import Process
def ping_response():
print("Sleeping")
time.sleep(5)
c = zerorpc.Client()
c.connect("tcp://127.0.0.1:4243")
print("sending pong")
c.pong()
class Api(object):
def echo(self, text):
"""echo any text"""
return text
def ping(self):
p = Process(target=ping_response, args=())
p.start()
print("got ping")
return
def parse_port():
port = 4242
try:
port = int(sys.argv[1])
except Exception as e:
pass
return '{}'.format(port)
def main():
addr = 'tcp://127.0.0.1:' + parse_port()
s = zerorpc.Server(Api())
s.bind(addr)
print('start running on {}'.format(addr))
s.run()
if __name__ == '__main__':
main()
Each time ping() is called from javascript side it will start a new process that simulates some work (sleeping for 5 seconds) and replies by calling pong on nodejs server to indicate work is done.
The issue is that the pong() request never gets to javascript side. If instead of spawning a new process I create a new thread using _thread and execute the same code in ping_response(), the pong request arrives in the javascript side. Also if I manually run the bash command zerorpc tcp://localhost:4243 pong I can see that the pong request is received by the nodejs script so the server on the javascript side works ok.
What happens with zerorpc client when I create a new process and it doesn't manage to send the request ?
Thank you.
EDIT
It seems it gets stuck in c.pong()
Try using gipc.start_process() from the gipc module (via pip) instead of multiprocessing.Process(). It creates a new gevent context which otherwise multiprocessing will accidentally inherit.
I've created a simple test app (Python 2.6.1) that runs a ThreadingTCPServer, based on the example here. If the client sends a command "bye" I want to shut down the server and exit cleanly from the application. The exit part works OK, but when I try to re-run the app, I get:
socket.error: [Errno 48] Address already in use
I tried the solution given here for setting the socket options but that didn't seem to help. I've tried various ways to close the server down, but always get the same error.
Any idea what I'm doing wrong?
import SocketServer
import socket
import sys
import threading
import time
class RequestHandler(SocketServer.BaseRequestHandler):
def setup(self):
print("Connection received from %s" % str(self.client_address))
self.request.send("Welcome!\n")
def handle(self):
while 1:
data = self.request.recv(1024)
if (data.strip() == 'bye'):
print("Leaving server.")
self.finish()
self.server.shutdown()
# None of these things seem to work either
#time.sleep(2)
#del self.server.socket
#self.server.socket.shutdown(socket.SHUT_WR)
#self.server.socket.close()
#self.server.server_close()
break
def finish(self):
self.request.send("Goodbye! Please come back soon.")
if __name__ == "__main__":
server = SocketServer.ThreadingTCPServer(("localhost", 9999), RequestHandler)
# This doesn't seem to help.
#server.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
#server.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.serve_forever()
print("Exiting program.")
If you have not already found an answer, I believe this may assist...
How to close a socket left open by a killed program?
However, this is the same solution offered by Alex, so perhaps this is just an opportunity to close an old question.
I have a class that I wish to test via SimpleXMLRPCServer in python. The way I have my unit test set up is that I create a new thread, and start SimpleXMLRPCServer in that. Then I run all the test, and finally shut down.
This is my ServerThread:
class ServerThread(Thread):
running = True
def run(self):
self.server = #Creates and starts SimpleXMLRPCServer
while (self.running):
self.server.handle_request()
def stop(self):
self.running = False
self.server.server_close()
The problem is, that calling ServerThread.stop(), followed by Thread.stop() and Thread.join() will not cause the thread to stop properly if it's already waiting for a request in handle_request. And since there doesn't seem to be any interrupt or timeout mechanisms here that I can use, I am at a loss for how I can cleanly shut down the server thread.
I had the same problem and after hours of research i solved it by switching from using my own handle_request() loop to serve_forever() to start the server.
serve_forever() starts an internal loop like yours. This loop can be stopped by calling shutdown(). After stopping the loop it is possible to stop the server with server_close().
I don't know why this works and the handle_request() loop don't, but it does ;P
Here is my code:
from threading import Thread
from xmlrpc.server import SimpleXMLRPCServer
from pyWebService.server.service.WebServiceRequestHandler import WebServiceRquestHandler
class WebServiceServer(Thread):
def __init__(self, ip, port):
super(WebServiceServer, self).__init__()
self.running = True
self.server = SimpleXMLRPCServer((ip, port),requestHandler=WebServiceRquestHandler)
self.server.register_introspection_functions()
def register_function(self, function):
self.server.register_function(function)
def run(self):
self.server.serve_forever()
def stop_server(self):
self.server.shutdown()
self.server.server_close()
print("starting server")
webService = WebServiceServer("localhost", 8010)
webService.start()
print("stopping server")
webService.stop_server()
webService.join()
print("server stopped")
Two suggestions.
Suggestion One is to use a separate process instead of a separate thread.
Create a stand-alone XMLRPC server program.
Start it with subprocess.Popen().
Kill it when the test is done. In standard OS's (not Windows) the kill works nicely. In Windows, however, there's no trivial kill function, but there are recipes for this.
The other suggestion is to have a function in your XMLRPC server which causes server self-destruction. You define a function that calls sys.exit() or os.abort() or raises a similar exception that will stop the process.
This is my way. send SIGTERM to self. (Works for me)
Server code
import os
import signal
import xmlrpc.server
server = xmlrpc.server.SimpleXMLRPCServer(("0.0.0.0", 8000))
server.register_function(lambda: os.kill(os.getpid(), signal.SIGTERM), 'quit')
server.serve_forever()
Client code
import xmlrpc.client
c = xmlrpc.client.ServerProxy("http://localhost:8000")
try:
c.quit()
except ConnectionRefusedError:
pass