Netcat Socket Programming - c

I am facing some issues to solve a problem. A server program is giving 4 random unsigned integer numbers everytime I connect to it. My job is to add the 4 numbers and send back the sum. But the time is restricted. So if I want to use a calculator to do the job, it is not possible. Thus I have to take resort to scripting. I want to connect to the the server using netcat, retrieve the 16 bytes, pipe the data to my C program(which will parse the data into 4 unsigned int variables and print out the sum) and again redirect this program output to netcat
netcat <server> <port> | myProg | netcat <server> <port>
But the tcp socket netcat is opening second time is not the previous socket. So a different set of 4 numbers would be presented this time, which defeats the entire effort. My question is: Is it possible by any means(using netcat) to use the previous socket (opened by netcat) to pump the calculated sum back to the server?
I dont want to use C to do socket programming as it is very tough for me.
Also I know
echo 3<>/dev/tcp/server/port
cat <&3 | ./myprog | more >&3
probably will solve my purpose (correct me if I am wrong). But I would like to do it the netcat way. Thanks in advance.

Use socat instead of netcat.
socat can spawn the command itself, with input and output both redirected (you don't use shell redirection, let socat handle it)
socat TCP:server,port SYSTEM:myProg

Related

Execute shell command from C environment and redirect output

I have seen there are some questions about this topic, but none of the answers satisfied me. Here is the problem: I need to write two sockets (client and server), with the client having to send to the server an awk program with some lines of input. No problem in sending strings back and forth between the sockets. Supposing I have stored the program in a string command and the string I should pass to it in input, I have tried this:
execl("/usr/bin/awk", command, input, (char *)0);
And this works, the awk program runs and it writes on the server's stdout and stderr. Thing is, if there are lines with errors, I need to send these back to the client, which is pretty impossible since execl doesn't give me the chance to store its output in arrays. So, does anybody know a way to do this without using system and popen?

How can I delete a UNIX Domain Socket file when I exit my application?

I have a server application that creates a UNIX Domain Socket in a specific path with a name and bind()s to it.
I need to delete the socket only when I close/stop the application intentionally, from within the the application code; otherwise it needs to be open. How do I do this?
Thanks!
Edit: Consider that I start and run my application from inside a terminal.
You're making this harder than it needs to be. Put the unlink() right before the bind(). That's how everybody else does it. (Example: BSD syslogd, one of the classic unix-domain-socket-based services)
If you have multiple exit points from your application and you don't want to modify each of them to call cleanup routine, then you may use "dirty" approach.
When socket is just created, register cleanup routine with atexit(3). Routine (which is simply a call to unlink(2)) will be called when application is terminated normally. But it won't be called if application is terminated with signal. So, if you want to cleanup after receiving SIGINT and similar signals, you also need to setup signal handlers properly.
You can check if socket if active by looking at /proc/net/unix. Then delete, ether in a cron, or before you start/restart your application.
echo "active sockets in /path/"
cat /proc/net/unix | grep -Eo '/path/.*'
echo "all sockets in path including stale sockets"
ls -1F /path/ | egrep '=$' | sed 's/=$//'
echo "example command to remove stale sockets"
comm -1 -3 <(cat /proc/net/unix | grep -Eo '/path/.*' | sort) <(ls -1F /path/ | egrep '=$' | sed 's/=$//' | sort) | xargs -n1 echo rm
Just execute
unlink("Path/to/Socket");
before you exit your program.
You can remove the socket file with a simple:
unlink(path);
Wherever you program exit your program, check if it exists, and remove it.
If you are using Linux, you can use an abstract namespace socket: Set the first byte in the sockaddr_un.sun_path to \0, and with bytes still in this array. An abstract socket is not placed on the filesystem, which has mild side effects.
References
https://gavv.net/articles/unix-socket-reuse/
man 7 unix
Abstract sockets
Socket permissions have no meaning for abstract sockets: the process umask(2) has no effect when binding an abstract socket, and changing the ownership and permissions of the object (via fchown(2) and fchmod(2)) has no effect on the accessibility of the socket.
Abstract sockets automatically disappear when all open references to the socket are closed.
The abstract socket namespace is a nonportable Linux extension.

HTTP Server with Redis Event Loop

I'm a newbie, and I was trying to test the code here (which uses Redis event loop)
But when i make a request to 127.0.0.1:8000, the server doesn't send the response, it hangs. Do i need to make some changes ? I just need the request to be echoed back, which the example intends to do.
Why do you think this thing is a HTTP server? It is not. It is a broken TCP echo server.
It is broken, because the write operation is not under the control of the event loop. Some bytes will be lost if the non blocking write operation cannot send all the bytes (you have no such guarantee).
Now, if you use a proper client, this program can still be demonstrated:
$ telnet 127.0.0.1 8000
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
toto
toto
titi
titi
tutu
tutu
... while the output of the program itself is:
Accepted 127.0.0.1:48645
If you want to play with event loops, I would suggest picking one among the following list. They are probably much better documented than the first random ae hack found on github ...
libevent
libev
libuv

Using Linux Shell to run a Client - Server for numbers of time

I'm coded two programs, one is Server, the other is Client.
The purpose of these two programs is file transfer. First, the Server program will be started up, then the Client program. the client program will receive a file from server.
I want to run a test to see how much time will the transfer be for many file sizes. Each file size I will do about 10 times.
The code is ok. When I write two scripts like this:
#!/bin/bash
time=$1
for((n=0;n<time;n++))
do
./server "3mb.MP3"
done
#!/bin/bash
time=$1
for((n=0;n<time;n++))
do
./client $n
done
And run the Server script first and then the client script. I realize that because of for loop, many instances of server are created and so the client. I just want one client and one server communicate with each other at a time. When the file transfer is over, we will create a new pair of client-server.
Is there any solution?
Thank you!
(I'm using Ubuntu 12.04.)
Just do a global for loop instead of loops for each client and server, if you need is one client-server per iteration. Something like --
time=$1
for((n=0;n<time;n++))
do
./server "3mb.MP3"
./client $n
done
To find the execution time of your script, you can use time ./x.sh which will give you the execution time of the overall script...if you want execution time for each iteration, then you have find start and end times for each loop and subtract the later from the former.
Surely it's as simple as
#!/bin/bash
time=$1
for((n=0;n<time;n++))
do
./server "3mb.MP3"
./client $n
done
You might need this if your server isn't forking internally:
#!/bin/bash
time=$1
for((n=0;n<time;n++))
do
./server "3mb.MP3" &
./client $n
done
The ampersand causes the shell not to wait for the server process to finish.
(Thanks to Floris)

Calling tftp get command from c source code

I'm calling system command
system("tftp -m binary 192.168.1.1 -c get myfile > /dev/null") ;
it works fine when tftp server is running but it makes my c program crashed when tftp server is off.
Is there a way to check whether the server is available or not in c source code ?
I think your problem lies not in the availability of the server, but the fact that tftp (at least on my Ubuntu box) does not support the command-line arguments you've provided. As a matter of fact, the only command-line argument that it does support is the name of the server.
However, you could try piping commands into tftp (simulating an interactive session), like so:
system( "echo -e \"binary\\nget myfile\\nquit\" | tftp 192.168.1.1" );
If the server isn't available, it'll time out after a few seconds and return control to your program.
system("echo -e \"timeout 1\\nget myfile\" | tftp 192.168.1.1");
I used timeout options instead of quit command because actual latency which makes my program watchdog reset is performing on get command execution. So quit can not prevent this.
On the otherhand I decided to call tftp command on a bash script starting my c program.
I think that calling tftp commad on a real time c program is faulty.
Many thanks Ethan .

Resources