5

I want to build a script that can be controlled while running from another scripts. For example I want to run my script like this:

~: Server &

and be able to run one of it's functions like:

~: client func1

Upon my searches I find signal module that have something like I want, but it's signals are predefined and I can not send signals of my own.

I even though of a client/server implementation using a network framework but I think it's too much for the abilities that I want my script to have.

Thank you all.

Shahin
  • 1,415
  • 4
  • 22
  • 33
  • Are you assuming that the client and server are running on the same machine? If not, you will need networking. – merlin2011 Apr 18 '14 at 06:02
  • I use Gtk signals - whitout a window or graphic part - and everithing is ok and fast. But I use Openbox/Gnome. I think platform-native signal method do the job with litle overhead. – cox Apr 18 '14 at 06:16
  • @merlin2011 I prefer to assume the client and server are running on the same machine since in other way as I said it'll be too far more than what I want! – Shahin Apr 18 '14 at 06:40
  • @Shahinism, I would not be so sure. I am preparing an answer for you which I think you'll find simpler than you expect. – merlin2011 Apr 18 '14 at 06:42
  • @merlin2011 Thank you, as you and oodograss said, socket was the solution. – Shahin Apr 18 '14 at 07:17
  • @Shahinism, You are welcome. I hope others will find the sample code below useful too. :) – merlin2011 Apr 18 '14 at 07:24

2 Answers2

11

If you are only trying to send commands one-directionally to a server, it is easier than you think, using Python's Sockets. The code samples are of course barebones in the sense that they do not do error handling, and do not call recv multiple times to make sure the message is complete. This is just to give you an idea of how few lines of code it takes to process commands.

Here is a server program that simply receives messages and prints to stdout. Note that we use threading so that the server can listen to multiple clients at once.

import socket
from threading import Thread


MAX_LENGTH = 4096

def handle(clientsocket):
  while 1:
    buf = clientsocket.recv(MAX_LENGTH)
    if buf == '': return #client terminated connection
    print buf

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

PORT = 10000
HOST = '127.0.0.1'

serversocket.bind((HOST, PORT))
serversocket.listen(10)

while 1:
    #accept connections from outside
    (clientsocket, address) = serversocket.accept()

    ct = Thread(target=handle, args=(clientsocket,))
    ct.start()

Here is a client program that sends commands to it.

import socket
import sys


HOST = '127.0.0.1'
PORT = 10000
s = socket.socket()
s.connect((HOST, PORT))

while 1:
    msg = raw_input("Command To Send: ")
    if msg == "close":
       s.close()
       sys.exit(0)
    s.send(msg)
merlin2011
  • 71,677
  • 44
  • 195
  • 329
  • @Shahinism, Thank you for the edits. As you can see, I did not get everything when I was stripping down these examples. :P – merlin2011 Apr 18 '14 at 07:54
  • Can you broadcast a message to multiple instances of the interpreter? Like if you have a web server running, can you broadcast a signal to every handler that is currently running and say "Log out your user if he has this id"? – KevinOrr Jul 06 '14 at 17:32
  • 1
    @KevinOrr, I think you are looking for [this question](http://stackoverflow.com/questions/603852/multicast-in-python), but if that is insufficient to help you, please ask a new question. – merlin2011 Jul 06 '14 at 17:56
  • 1
    I tried to fix/edit a bug in the above code, but it got rejected for some reason. Anyway, the thread in the server code is started using `ct.run()` instead of `ct.start()` which means it's not actually executing in parallel (as a thread) but as a normal blocking code. This means that multiple connections cannot be handled simultaneously as intended by the threading and statement `serversocket.listen(10)`. I.e, the function `accept()` will only be reached when a client is finished with it's connection in the handling function. – André C. Andersen Oct 24 '16 at 09:39
4

So you need to talk to a running process right? What about the idea of unix domain socket?

In your server you can build up a socket on a path of your unix file system, then talk to that socket in you client, like described in this link I googled:

http://pymotw.com/2/socket/uds.html

oodograss
  • 188
  • 1
  • 5