Reputation: 1772
I am currently working on a project to learn about signals, basically I have a client and a server, the server gives out a pid that I must input as a parameter to the client with a string, after being launched, the client sends this string to the server and the server displays it.
What I've done so far is convert the string into binary and if the integer is a 0 I send SIGUSR1 otherwise (if it's a 1) I send SIGUSR2, that way I want to convert the binary to the string we had previously but I am wondering how I could do so.
Here is the main for the server, as you can see it displays its pid (so we can launch the client later with it) and waits for a signal. Once it catches one it calles my_sig (that you will find later in this thread).
int main()
{
int pid;
pid = getpid();
printf("Server pid is: %d\n", pid);
if (signal(SIGUSR1, my_sig) == SIG_ERR)
{
printf("Error.\n");
exit(1);
}
if (signal(SIGUSR2, my_sig) == SIG_ERR)
{
printf("Error.\n");
exit(1);
}
while (1);
}
And here is the very simple my_sig, as you can see if it receives SIGUSR1 as a signal it displays a 0, otherwise a 1.
void my_sig(int param)
{
char *src;
char *dest;
if (param == SIGUSR1)
{
my_printf("0");
}
if (param == SIGUSR2)
{
my_printf("1");
}
}
So at the end of the day what it does is display the word given in the client in binary char by char.
How could I use that to display the string I inputted in the client?
Thanks guys, if you need any precisions please let me know.
EDIT : As much as I would love to know about other signals, sadly, I am limited to these ones for this project.
Upvotes: 2
Views: 1583
Reputation: 58589
Signals are largely inappropriate for this task, as it is possible to lose information depending on timing.
Standard signals will lose bits and ordering. These signals are individually named (e.g., SIGUSR1, SIGUSR2), and do not queue. That is, only one instance of any given standard signal can be pending at any time. Additionally, their order of delivery is not guaranteed, but in practice is often lowest to highest. Thus, if I sent your process USR2, USR2, USR1, USR1, USR2, USR2 and got the timing just right, your process might receive a single USR1 followed by a single USR2.
Real-time signals will lose your ordering. These signals are numbered in the range SIGRTMIN to SIGRTMAX, they do queue, and they have a defined delivery order. Unfortunately, that order is lowest to highest and thus presents a similar problem as above. (You'd receive MIN+0, MIN+0, MIN+1, MIN+1, MIN+1, MIN+1.)
(If you used sigaction
rather than signal
, and if you specified SA_SIGINFO in your signal handler registration, and if the signaling application used sigqueue
to send an int along with a chosen real-time signal via sival_int
, then you could transmit ones and zeros in sequence via signals. That's rather a tortured use case, however.)
Upvotes: 1
Reputation: 67
Using signals to transmit binary data would be both slow and inefficient. If you still insist on doing it, you would have to pack the bits into bytes rather than printing "1" or "0"
Here is one way you might do it.
#define MAX_BYTES 64
static int current_bit=0,current_byte=0;
static char byte=0,output_bytes[MAX_BYTES];
void my_sig(int param){
char *src;
char *dest;
if (param == SIGUSR1)
{
byte &= ~(128 >> current_bit);
}
if (param == SIGUSR2)
{
byte |= (128 >> current_bit);
}
current_bit++;
if(current_bit > 7){
current_bit = 0;
output_byte[current_byte] = byte;
byte = 0;
if(current_byte < (MAX_BYTES-1)){
current_byte++;
}
}
}
That is poor code. But the idea of sending data of signals isn't a good one anyway.
Output would be in the output_byte array.
Upvotes: 0