Ping servers and check the result from C program? - c

This is My last question. Now my new requirement is to ping some set of servers and check if they are replying or not. I am trying my way of
system("ping xxx.xx.xx.xx >out.txt");
And then parsing the out.txt for a string "Request timed out.".
This is yielding me good results. But is there any better way to do from c program. Non programmatic ways are also welcome. But mostly I want to go by C program. If the request is timed out I will send a mail through same my way by php. Thanks in advance.
My environment : windows, Tiny C Compiler

A better method for capturing output than system() is to use popen() instead. That way you can capture the output of the command without using a temporary file.
A better method for pinging is to use the Microsoft ICMP API (an introductory page can be found here). This will be possible if your C compiler has the ability to call arbitrary Win32 API functions. In particular, IcmpSendEcho is the function you would want.

Another option is using raw sockets for sending/receiving ICMP packets yourself, or using a library such as libnet for that. You can then take your measurements at a finer granularity. It'll take some time and getting used to, though. :)

Related

How do I get PID from socket port on Windows?

Given a socket port how do you find the process ID (process name) of the process on Windows 10 that uses this port? I am aware of netstat command but I would like to do it with C code only.
How about there, it appears there's a way: the IP Helper library.
Ref: https://learn.microsoft.com/en-us/windows/win32/iphlp/ip-helper-start-page
I haven't used it for this, but it's clearly going down the right road by providing everything you need to basically roll your own netstat.exe.
The low-level object that contains all the info is MIB_TCPROW2, which has the local and remote address + port, plus dwOwningPid. So we know there's a way.
Drilling down we ultimately need the GetTcpTable2() call, and Microsoft's web page helpfully has what appears to be fully-functional C code to do all this yourself.
https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-gettcptable2
Finding this was the best surprise of my day!

sysfs, ifreq, IOCTL or ??? to programatically monitor network status

We have an embedded SoC running BusyBox Linux (kernel 2.6.x), and we have a need to monitor or at least notice in a timely manner when the network connection goes down or comes up (catching other events would be good but not essential).
I've spent a long time googling & reading SO threads and there seems to be a ton of different answers depending on the exact task at hand on the particular OS and the phases of the moon etc.
Our specific criteria are:
We are looking from inside a C program, so C code is preferable to command line calls.
Although the interface is always there, we can't guarantee it is or has ever been up (I have seen comments on some examples that only work when the interface is up even if the link is down)
It would be nice not to have to poll, but rather to send/catch status change messages as and when they happen. I believe the kernel may already get such messages from the driver, but I'm not sure if there's anything we can hook into?
I've narrowed the likely seeming answers down to a few candidates but can't work out which is the nicest (least overhead, most reliable, least likely to break in future versions):
cat sys/class/net/eth0/operstate
cat sys/class/net/eth0/carrier (I can find no good explanation of the difference between these two)
Using ifreq or various sequences of ioctl calls to read the socket status (looks kinda messy to me) as per answers here and here (more tidy looking).
Somehow catch status change messages???
You can use inotify to keep check on the /sys/class/net/eth0/operstate. Inotify allows different events to be watched on specified file or directory e.g. CREATE, MODIFY, WRITE etc.
You can seen the working example here

Howto combine TCP and UDP in a single Server?

I am totally new to socket programming and I want to program a combined TCP/UDP-Server socket in C but I don't know how to combine those two.
So at the moment, I do know how TCP- and UDP-Server/-Clients work and I have already coded the Clients for TCP and UDP. I also know that I have to use the select()-function somehow, but I don't know how to do it.
I have to read two numbers, which are sent to the TCP-/UDP-Server with either TCP- or UDP-Clients and then do some calculations with these numbers and then print the result on the server.
Does anyone know a tutorial for that or an example code or can help me with that?
Or at least a good explanation of the select() function.
Basically, use an event loop. It works like this:
Is there anything I need to do now? If so, do it.
Compute how long until I next need to do something.
Call select specifying all sockets I'm willing to read from in the read set and all sockets I'm trying to write to in the write set.
If we discovered any sockets that are ready for reading, read from them.
If we discovered any sockets that are ready from writing, try to write to them. If we wrote everything we need to write, remove them from the write set.
Go to step 1.
Generally, to write to a socket, you follow this logic:
Am I already trying to write to this socket? If so, just add this to the queue and we're done.
Try to write the data to the socket. If we sent it all, we're done.
Save the leftover in the queue and add this socket to our write set.
Three things to keep in mind:
You must set all sockets non-blocking.
Make sure to copy your file descriptor sets before you pass them to select because select modifies them.
For TCP connections, you will probably need your own write queue.
The idea is to mix inside your server a TCP part and a UDP part.
Then you multiplex the inputs. You could use the old select(2) multiplexing call, but it has limitations (google for C10K problem). Using the poll(2)
multiplexing call is preferable.
You may want to use some event loop libraries, like libev (which uses select or poll or some fancier mechanisms like epoll). BTW, graphical toolkits (e.g. GTK or Qt) also provide their own even loop machinery.
Read some good Linux programming book like the Advanced Linux Programming
book (available online) which has good chapters about multiplexing syscalls and event loops. These are too complex to be explained well in a few minutes in such an answer. Books explain them better.
1) Simple write a tcp/udp server code, and when receive the message, just print it out.
2) substitute print code to process_message() function.
Then you have successfully combine TCP and UDP server to the same procedure.
Be careful with your handling procedure, it's should be cope with parellel execution.
You may try this stream_route_handler, it is c/c++ application, you can add tcp/udp handler in your single c/c++ application. This has been using by transportation heavy traffic route, and logging service purpose.
Example of using
void read_data(srh_request_t *req);
void read_data(srh_request_t *req) {
char *a = "CAUSE ERROR FREE INVALID";
if (strncmp( (char*)req->in_buff->start, "ERROR", 5) == 0) {
free(a);
}
// printf("%d, %.*s\n", i++, (int) (req->in_buff->end - req->in_buff->start), req->in_buff->start);
srh_write_output_buffer_l(req, req->in_buff->start, (req->in_buff->end - req->in_buff->start));
// printf("%d, %.*s\n", i++, (int) (req->out_buff->end - req->out_buff->start), req->out_buff->start);
}
int main(void) {
srh_instance_t * instance = srh_create_routing_instance(24, NULL, NULL);
srh_add_udp_fd(instance, 12345, read_data, 1024);
srh_add_tcp_fd(instance, 3232, read_data, 64);
srh_start(instance);
return 0;
}
If you are using C++ program, you may like this sample code.
stream route with spdlog

uart buffer is not read

I am trying to read binary data from a serial device in c on linux.
The problem is, that sometimes there are chars in the driver's internal buffer, but polling (with select(2)) returns saying the device is not ready to be read.
I have read and re-read the man of termios and all the related man and searched over the internet. I believe I set all the flags correctly (namely VTIME, VMIN) and unset ICANON.
I tried using the function "tcmakeraw", as well, but it didn't solve the problem.
Do you guys have any ideas about what should I do?
Kind regards & Thanks in advance
Yannay
You should show us the code. I would start with using cfmakeraw on the serial port.
Once you have things working in raw mode, you can make modification and see how it works.
Here is a list of question or things you could check :
after modifying the attribute, using for example cfmakeraw, do you call tcsetattr(...) to
apply your change ?
How do you prove there is still data in the driver receive buffer ?
do you check your system call for errors ?
what is the result of stracing your program ?
Edit based on your comments :
Your protocol "guarantee" .... => check your assumption ! Unchecked, crystal clear guarantee are a good coandidate for "impossible error"
Basically : either select is broken, or your serial driver. Reason for serial driver being broken is a hardware fifo not being full enough to trigger un interrupt, or loosing an interrupt.
What happens when you read directly (not through C) /dev/ttyS0 (or equiv) after you setserial your parameters. Are you able to get the needed data outside of the select()?

Send messages to program through command line

I have this program, we'll call it Host. Host does all kinds of good stuff, but it needs to be able to accept input through the command line while it's running. This means it has to somehow send its other process data and then quit. For example, I need to be able to do this:
./Host --blahblah 3 6 3 5
This should somehow end up calling some function in Host called
handleBlahBlah(int x1, int y1, int x2, int y2){
//do some more sweet stuff
}
Host is a C program, and does not need to support multiple instances.
An example of this is Amarok music player. With Amarok running and playing, you can type "amarok --pause" and it will pause the music.
I need to be able to do this in Linux or Windows. Preferably Linux.
What is the cleanest way to implement this?
If you were on Windows, I'd tell you to use a hidden window to receive the messages, but since you used ./, I assume you want something Unix-based.
In that case, I'd go with a named pipe. Sun has a tutorial about named pipes that might be useful.
The program would probably create the pipe and listen. You could have a separate command-line script which would open the pipe and just echo its command-line arguments to it.
You could modify your program to support the command-line sending instead of using a separate script. You'd do the same basic thing in that case. Your program would look at it's command-line arguments, and if applicable, open the pipe to the "main" instance of the program, and send the arguments through.
If it needs to be cross-platform, you might want to consider making the running instance listen on a TCP port, and have the instance you fire up from the command-line send a message to that port.
I suggest using either a Unix socket or D-Bus. Using a socket might be faster if you're familiar with Unix sockets programming and only want a few operations, whereas D-Bus might make it easier to concentrate on implementing the functionality in a familiar object-oriented way.
Take a look at Beej's Guide to Unix IPC, particularly the chapter on Unix sockets.
What no one has said here is this:
"you can't get there from here".
The command line is only available as it was when your program was invoked.
The example of invoking "fillinthename arguments ..." to communicate with fillinthename once fillinthename is running can only be accomplished by using two instances of the program which communicate with each other.
The other answers suggest ways to achieve the communication.
An amarok like program needs to detect the existence of another instance
of itself in order to know which role it must play, the major role of
persistent message receiver/server, or the minor role of one shot
message sender.
edited to make the word fillinthename actually be displayed.
One technique I have seen is to have your Host program be merely a "shell" for your real program. For example when you launch your application normally (e.g.: ./Host), the program will fork into the "main app" part of your code. When you launch your program in a way that suggests you want to signal the running instance (e.g.: ./Host --send-message restart), the program will fork into the "message sender" part of your code. It's like having two apps in one. Another option that doesn't use fork is to make Host purely a "message sender" app and have your "main app" as a separate executable (e.g.: Host_core) that Host can launch separately.
The "main app" part of your program will need to open up some kind of a communication channel to receive messages, and the "message sender" part will need to connect to that channel and use it to send messages. There are several different options available for sending messages between processes. Some of the more common methods are pipes and sockets. Depending on your OS, you may have additional options available; for instance, QNX has channels and BeOS/Haiku have BMessages. You may also be able to find a library that neatly wraps up this functionality, such as lcm.
So, I may be missing the point here, but by deafult a C program's main function takes two arguments; argc, a count of the number of arguments (at least one), and argv (or arg vector), the argument list. You could just parse through the arguments and call the correct method.
For example:
int main(int argc, *argv[])
{
/*loop through each argument and take action*/
while (--argc > 0)
{
printf(%s%s, *++argv, (argc > 1) ? " " : "");
}
}
would print all of the arguments to screen. I am no C guru, so I hope I haven't made any mistakes.
EDIT: Ok, he was after something else, but it wasn't really clear before the question was edited. Don't have to jump on my rep...

Resources