What's the conventional way to send commands to running processes? - sockets

Is there a conventional way to write a program such that commands can be issued to the program from the command line without a repl? For example, how you can send commands to a running nginx server using sudo /etc/init.d/nginx restart (or any other valid command besides restart)
One idea I had was having the long-running program create and monitor a unix socket that other programs can write to to send it commands. Another was to create a local server with a REST interface that can be sent commands that way, though that seems a bit gross.
What's the right way to do this?

Both ways are ok, and you could even consider using some RPC machinery, such as making your application serve JSONRPC on some unix(7) socket. Or use a fifo(7). Or use D-Bus.
A common habit on Unix is to have applications reload their configuration files on e.g. SIGHUP signal, and save some persistent state (before terminating) on SIGTERM. Read signal(7) (notice that only async-signal-safe routines can be called fro signal handlers; a good way is to only set some volatile sig_atomic_t variable inside the handler and test it outside). See also POSIX signal.h documentation.
You might make your application become a specialized HTTP server (e.g. using some HTTP server library like libonion) and give it some Web interface (or REST, or SOAP ...); the user (or sysadmin) will then use his browser to interact with your application.
You could make your server systemd compatible. (I don't know exactly what that requires, it is perhaps D-bus related).
You could embed some command interpreter (like Guile and Lua) in your app and have some limited kind of REPL loop running on some IPC like a socket or a fifo. Beware of nasty code injection.

I had a similar issue where I have a plethora of services running on any number of machines and each is in need of communicating with several others.
My main problem was not so much the communication between the services. That can be done with a simple message sent over a connection (as Basile mentioned, it can be TCP, UDP, Unix sockets, FIFOs...). However, when you have over 20 services, many of which need to communicate with several other services, you start having a headache on how to get all the connections right (I have such a system, although it has a relatively limited number of services, like just 10 and that's already very complicated).
So I created a process (yet another service) called Communicator. All services connect to the Communicator service and when they need to send a message, they include the name of the service they want to reach. The Communicator service is in charge of sending the message to the right placeā€”i.e. it could be to another Communicator service running on a different computer. Communicator has a graph of all the services available on your network and knows how to send messages to them without your service having to know anything about all of that. Computing a graph can be really complex.
For the purpose, I created the eventdispatcher project. It is in C++, which may not be what you're interested in, although you could use it in other languages that interface with C/C++. The structure of the messages are "proprietary" (specific to the Communicator), but you can create any message you want. A message includes a name and parameters (param-name=value). The first version has a simple one line text communication system. The newer version accepts JSON as well (still must be one line of text per message).
The system supports TCP, UDP, Unix sockets, FIFO, and between threads, you can have thread safe fifos. It also understand signals (like SIGHUP, SIGTERM, etc.) It has a specific connection to listen for the death of a thread. It supports encryption over TCP via OpenSSL. The messages can automatically be dispatched (hence the current name of the library). Connections are assigned a timer. And there are CUI and GUI (Qt) extensions as well.
The one main point here is that all your connections can be polled (see poll()) and thus you can implement a system that reacts to events instead of a system which sleeps and checks for events, sleeps and check, etc. or worth, you have a single blocking connection and everything has to happen on that one connection or your service gets stuck. This is one reason Unix has been using signals since early version of Unix did not have select() nor poll().

Related

Is the OS always the server?

Given the server-client model, would the OS initiate messages to applications, or is message passing always initiated by programs that want to use resources and thus must communicate with the OS?
OS is an overloaded term, and application is a vague term.
A pure message passing OS might implement traditional (unix) system calls in applications. For example, you might have an application called FileSystem, which accepts messages like Read,Write,Open,Close.... In these, such an application would be considered a server, and the client would be an application which wanted to use the File Services.
Pure message passing systems typically have difficulty with asynchronous events. When you look at implementing a normal read system call in a message passing system, it is natural that it will be an RPC: the client sends a read request, then suspends until the server has satisfied the read and sent a reply.
When the client wants asynchronous notification, such as send me a message when there is new mouse events available; the RPC somewhat falls down. While purely asynchronous systems exist, they are cumbersome to use with plain old programming languages like C, C++, ... There is hope that message based languages like Golang can break the impass, but that is yet to be seen.
Higher level OS-like services may deploy a number of interaction methods, quite distinct from client serve. Publish-Subscribe, a more recent reimplmentation of the 1980s multi-catch, has been popular in the last decade. Clients subscribe to a set of channels that they are interested in, and every event delivered to that channel is copied to every client subscribed to the channel before it is retired. Normal clients can generate events as well, so the mechanism serves as a dynamic interconnect between modules.
Dbus + zeromq are P-S systems of differing scales. Note that both can be implemented outside of a message passing OS.

Chat between server and client

I want to create a chat program between a server and a client, I want the client or server to be able to send message to the other end at anytime without waiting for example:
Client: hi
Server: hi
Server: I'm the server.
Server: How are you?
Client: Good.
In this example the Server doesn't wait for the Client to reply and sends another message at anytime.
Should I use the function select?, If so how should I determine the timeout and is the timeout value is the solution for busy waiting?
Is select function is the best approach for this problem?
Thanks.
Using select seems like the right approach, especially if you want the program to work on Windows. This will allow you to block the process and wait for a message from multiple clients simultaneously.
In general you should set the timeout to NULL so that the server will block indefinitely for a request from a client. The timeout is only useful if you want to additionally wake up the server at regular intervals for other reasons.
If you are targetting Unices (like Linux) it is easier and more efficient to use poll. This does basically the same thing but the interface is easier to work with. select becomes quite awkward to use if the file descriptor numbers become larger than 1024, which is a problem if you ever expect your server to handle large numbers of clients.
If you are targeting Linux specifically and don't care about portability you can even use epoll which has even more performance advantages and is arguably easier to use.
If you are only targeting Windows, you can create event objects for each of the sockets and then use WaitForMultipleObjectsEx to wait for data from any of them. This provides similar functionality to poll but the API is quite involved.

Winsock: Can i call send function at the same time for different socket?

Let's say, I have a server with many connected clients via TCP, i have a socket for every client and i have a sending and receiving thread for every client. Is it safe and possible to call send function at the same time as it will not call send function for same socket.
If it's safe and ok, Can i stream data to clients simultaneously without blocking send function for other clients ?
Thank you very much for answers.
Yes it is possible and thread-safe. You could have tested it, or worked out for yourself that IS, IIS, SQL Server etc. wouldn't work very well if it wasn't.
Assuming this is Windows from the tag of "Winsock".
This design (having a send/receive thread for every single connected client), overall, is not going to scale. Hopefully you are aware of that and you know that you have an extremely limited number of clients (even then, I wouldn't write it this way).
You don't need to have a thread pair for every single client.
You can serve tons of clients with a single thread using non-blocking IO and read/write ready notifications (either with select() or one of the varieties of Overlapped IO such as completion routines or completion ports). If you use completion ports you can set a pool of threads to handle socket IO and queue the work for your own worker thread or threads/threadpool.
Yes, you can send and receive to many sockets at once from different threads; but you shouldn't need those extra threads because you shouldn't be making blocking calls to send/recv at all. When you make a non-blocking call the amount that could be written immediately is written and the function returns, you then note how much was sent and ask for notification when the socket is next writable.
I think you might want to consider a different approach as this isn't simple stuff; if you're using .Net you might get by with building this with TcpListener or HttpListener (both of which use completion ports for you), though be aware that you can't easily disable Nagle's algorithm with those so if you need interactivity (think of the auto-complete on Google's search page) then you probably won't get the performance you want.

3-way communication via sockets

Good Afternoon Gurus,
I am pretty familiar with basic socket programming, and the IO::Socket module but I need to code something now that I have not encountered before. It will be a 3 tier application. The first tier is an event-loop that sends messages upstream when certain events are encountered. The second tier is the 'middle-ware' server, which (among other things) acts as the message repository. The third tier is a cgi application, which will update a graphical display.
I am confused on how to set up the server to accept uni-directional connections from multiple clients one one side, and communicate bi-directionally with the cgi application on the other. I can do either of those tasks separately, just not in the same script (yet). Does my question make sense? I would like to stick with using the IO::Socket module, but it is not a requirement by any means. I am not asking for polished code, just advice on setting up the socket(s) and how to communicate from one client to another via the server.
Also, does it make more sense to have the cgi application query the server for new messages, or have the server push the new message upstream to the cgi application? The graphical updates need to be near real-time.
Thank you in advance,
Daren
You said you already have an event loop in the first tier. In a way, your second-tier server should also arrange some kind of event loop for asynchronous processing. There are many ways to code it using perl, like AnyEvent, POE, Event to name just a few. In the end, they all use one of select, poll, epoll, kqueue OS facilities (or their equivalent on Windows). If you feel comfortable coding in a relatively low-level, you can just use perl's select builtin, or, alternatively, its object-oriented counterpart, IO::Select.
Basically you create two listening sockets (you might only need one if the first tier uses the same communication protocol as the third tier to talk to your server), add it to the IO::Select object and do a select on it. Once the connection
is made, you add the accepted sockets to the select object.
The select method of IO::Select will give you back a list of sockets ready for reading or writing (I am ignoring the possibility of exceptions here). Of course you have to keep track of your sockets to know which one is which. Also, the communication logic will be somewhat complicated because you have to use non-blocking sockets.
As for the second part of your question, I am a little bit confused what you mean by "cgi" - whether it is a Common Gateway Interface (i.e., server-side web scripts), or whether it is a shorthand for "computer graphics". In both cases I think that it makes sense for your task to use server push.
In the latter case that's all I'd like to say. In the former case, I suggest you google for "Comet" (as in "AJAX"). :-)
In a standard CGI application, I don't see how you can "push" data to them. For a client interaction, the data goes through the CGI/presentation layer to the middle tier to remain in session storage (or cache) or to the backend to get stored in the database.
That is of course unless you have a thick application layer which is a caching locus and kind of a middle tier in itself.

Which Interprocess Communication methods work on a Terminal Server?

In a terminal server session, some standard IPC technologies might not work like in a single user environment, because the required resources are not virtualized.
For example, TCP/IP ports are not virtualized, so applications in different sessions which try to listen on the same port will cause a port conflict.
Which IPC technology will work in a terminal server environment where applications running in the same user session need to interact?
Messages (WM_COPYDATA)?
Named Pipes?
DDE?
Memory Mapped Files?
Messages will work fine. DDE will too, since it is based on messages. Named pipes will not, since they are per-system and not per-session. You might also consider COM or OLE.
All IPCs can be used in a TS environment - you just have to be clever in the naming of the objects to achieve the required end result. Using sockets is trickier but it can be done. I've listed a few methods below.
For IPC objects that can be named (Pipe, Event, Mutex, Memory Mapped File etc.) incorporating the session ID into the name of the object will achieve the virtualisation required.
To further lock down the IPC object use the object's security attributes to stop the possibility of any other user from accessing the IPC object. This could occur accidentally as a result of a bug or maliciously from another user on the terminal server.
Similarly use the logged on user's Authentication ID in the IPC object's name. In C++ see MSDN on GetTokenInformation use TokenStatistics for the TokenInformationClass. I'm sure there is an equivalent .NET method. Again secure the IPC object.
If you must use sockets on a TS (I personally would choose another method to communicate between applications on a TS) then use the port numbers. Pick a base port number and add the session number to get the port used for a session. To make sure that the correct applications are communicating use an authentication method and/or handshaking before transfering data. Theoretically sessions can be numbered up to 65535 so you may come unstuck when you use a base port number of say 2000 and session your application is run in session 65500.
If you really wanted to use sockets then maybe a broker service would help.