I'm trying to create a basic server with a named pipe in windows. The problem occurs when trying to connect the pipes(I suspect).
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main(){
HANDLE p1, p2;
printf("Server...");
p1 = CreateNamedPipe(TEXT("\\\\.\\PIPE\\pipe1"),PIPE_ACCESS_INBOUND,PIPE_TYPE_BYTE|PIPE_WAIT,3,0,0,0,NULL);
p2 = CreateNamedPipe(TEXT("\\\\.\\PIPE\\pipe2"),PIPE_ACCESS_OUTBOUND,PIPE_TYPE_BYTE|PIPE_WAIT,3,0,0,0,NULL);
if(p1 == INVALID_HANDLE_VALUE || p2 == INVALID_HANDLE_VALUE ) { printf("pipe fail");exit(2);}
printf("1. Pipes created");
ConnectNamedPipe(p1,NULL);
ConnectNamedPipe(p2,NULL);
printf("2. Pipes connected");
DisconnectNamedPipe(p1);
DisconnectNamedPipe(p2);
CloseHandle(p1);
CloseHandle(p2);
printf("3. Pipes disconnected & closed");
printf("exit server...");
return 0;
}
When running the program, it doesn't print anything and when i manually stop it it just prints
Server...1. Pipes created (in my IDE console - Eclipse) or if I run program directly it, it prints the same then it holds.
It takes two to tango here. You'll need to write another program that calls CreateFile() to open the named pipe. Only then will the ConnectNamedPipe() call in your server program complete. Avoid using two pipes in your test program, pipes are bi-directional so you only need a single pipe to talk back-and-forth. If you want to support multiple clients then simply call ConnectNamedPipe again after a pipe connection was established. At which point it also becomes important to use overlapped I/O or threads.
Do take a look at the sample code included in the MSDN articles for named pipes. It shows you how to write both the server and client code.
Related
I have to use a fifo in my code.
I use sock to accept new client. For each client I create new thread to send and receive message to him.
In the function of the thread I use fifo to send and receive messages also to another process and here is my code:
int s_to_c=open(myfifo1,O_WRONLY);
int c_to_s=open(myfifo2,O_RDONLY);
char echoBuffer[RCVBUFSIZE];
int recvMsgSize;
for(;;)
{
bzero(echoBuffer,RCVBUFSIZE);
read(c_to_s, echoBuffer, RCVBUFSIZE);
write(sock, echoBuffer, strlen(echoBuffer));
bzero(echoBuffer,RCVBUFSIZE);
read(sock, echoBuffer, RCVBUFSIZE);
write(s_to_c,echoBuffer,strlen(echoBuffer));
}
close(c_to_s);
close(s_to_c);
close(sock);
And on the other side (The other process) my code:
int s_to_c=open(myfifo1,O_RDONLY);
int c_to_s=open(myfifo2,O_WRONLY);
char echoBuffer[RCVBUFSIZE];
int recvMsgSize;
for(;;)
{
bzero(echoBuffer,RCVBUFSIZE);
fgets(echoBuffer,RCVBUFSIZE,stdin);
echoBuffer[strlen(echoBuffer)-1]='\0';
write(c_to_s, echoBuffer, strlen(echoBuffer));
bzero(echoBuffer,RCVBUFSIZE);
read(s_to_c, echoBuffer, RCVBUFSIZE);
printf("%s\n", echoBuffer);
}
My problem is in this process : s_to_c and c_to_s take always the value(3,4).
So the first client connect correctly sending and receiving his message.
But when the second connect the first client become disable.And the messages of the second client sends and receives to and from the two processes.
Can I have some help please.Should I have to use tags for example??
select() allows you to check the status of a file descriptor (in your case the ones connected to your pipes). When select() returns, it tells you which pipes have data to process. That way, you can monitor many pipes in the server process.
The client process will always use the file descriptors 3 and 4 for the pipes since those are the first free ones after the stdio (0=stdin, 1=stdout, 2=stderr). So that is correct.
If you see the combination of 3 and 4 on your server as well, then you have a bug in the code where you create the pipes, not in the place where you use them.
If you use Linux, there is an easy way to see what a file descriptor is connected to: Look into /proc/PID/fd/ (replace PID with ID of the process that you want to examine) or use lsof -n -p PID (which shows a lot of other things as well like loaded shared libraries).
I have a long running program in C under Linux:
longrun.c
#include <stdio.h>
int main()
{
int mode=0;
int c=0;
while(1)
{
printf("\nrun # mode %d value : %d ",mode,c );
if (c>100)
c=0;
if(mode==0)
c++;
else
c=c+2;
sleep(3);
}
return 0;
}
It will display
run # mode 0 value : 0
run # mode 0 value : 1
run # mode 0 value : 2
I need to write another program in C (some thing like changemode.c) , so that it can communicate to the longrun.c
and set its value of mode to some other value, so that the running program will
display values in incremental order of 2.
I.e., if I am running the program after some x minutes , it will display in this pattern:
run # mode 0 value : nnn
run # mode 0 value : nnn+2
run # mode 0 value : (nnn+2)+2
I can do it using file method the changemode.c will create a file saying mode =2
then the longrun.c will everytime open and check and proceed. Is there some other better way to solve this, like interprocess communication?
If possible can any one write a sample of the changemode.c?
One of the most basic ideas in Unix programming is process forking, and the establishment of a pipe between the 2 processes. longrun could start by creating a pipe, calling fork, and using the parent process as the changemode 'monitor' process, and the child process as you use longrun now. You will need to periodically read / write on either end.
A google search will return many examples. Here's another.
The solution has two parts:
A communication channel between the two processes. Unix Domain Sockets are a good tool for it, and they behave similarly to TCP/IP sockets.
Replacing sleep with select. select will listen on the socket, handling communication with the other program. You can also specify a 3 second timeout, so when it returns 0 (meaning no activity on the socket), you know it's time to print some output.
As an alternative to #2, you could use two threads - one sleeping and producing output, the other handling the socket. Note that any data shared by the threads should be synchronized (in your very simple case, where there's just one integer, you probably need nothing, but you sure do when it gets more complicated).
As mentioned in other answers, you need some kind of inter-process communication. You can find more info on the topic in the "Beej guide to Unix IPC" (it's a "classic"), available at:
http://beej.us/guide/bgipc/
Fernando
Trying to open tty port using open system call. HOw do i know if this port is being used by another application in case the open system call returns -1?
DO not find error codes for the same.
a call to open() won't give you an error if the file is already open.
Howerver, you can try to analyze the output of the linux lsofcommand:
lsof /dev/ttyS0
It will return information about the processes that opened the given file (in this case: /dev/ttyS0).
(I've tested this a few times so I'm not sure about it, but lsof seems to return 0 if the file is opened by a process and return 1 if no process has opened it. This could be an indication, however I would suggest you really analyze the output of the command itself)
#include <errno.h>
#include <stdio.h>
#include <strcing.h>
int main()
{
if(open("/dev/ttyS0", O_RDWR))
printf("errno = %s\n", strerror(errno));
return errno;
}
see this link in order to figure out what the error code is.
here is the situation: I need to send a data to a neighbor(socket) and then switch to listening mode. Ive got a client part in client.c, which just listens, and server part in server.c - sends data. Using sockets I need to have a main() in both of them. How should I get them "cooperate" together, so both mainss are not going result in error?
Or any other ideas how to solve this issue with sending and listening?
Thanks in advance!
Lucas
You can always create two executables from the sources. Each of them will have its own main.
Or, you can create a single executable and let it fork another process or create another thread. When creating a new thread you'll specify the second "main" to be the thread function.
When fork-ing, you should create two functions main_server and main_client and let the actual main decide which of them to call, just after the fork. See snippet:
int main_server(int argc, int argv){
//TODO: complete
return 0;
}
int main_client(int argc, int argv){
//TODO: complete
return 0;
}
int main(int argc, int argv){
//TODO: parse args and get argv_server, argv_client, argc_server, argc_client
int pid = fork();
if (pid < 0) {
//TODO: handle error and leave
} else if (pid) {
// start client here for example
main_client(argc_client, argv_client);
} else {
main_server(argc_server, argv_server);
wait(pid);
}
return 0;
/* TODO: each of the above calls should be checked for errors */
}
Hope it helps.
Note: it's better to create a separate executable but if you are required to have only one, use the above snippet.
The thing to remember is that these programs will compile into separate binaries that become separate processes. You will start the "server" program (which will run its main) and then the client program (which will run its main). They communicate over the socket you're creating.
Another solution to do this is using "select()" method. This is only for the socket programming in Linux/Unix environment. Using this you can have both sending and listening task done in the same main(). Here's the tutorial for this method.
http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html#selectman
What it does is that instead of using fork() it puts all the sockets in a read_set. and then it goes into an infinite do-while() loop. Now this is very useful for socket programming in Linux/Unix. What happens in Linus/Unix each socket is assigned a File Descriptor(FD) in which they write the data and then it is transferred. It treats I/O console as a FD. So it puts the console FD in read_set, then all the other listening ports in read_set and then waits for the data from any of the above FD. So if you have data in console it will select that FD and perform the task you've written. Or will be in the listening mode until you close the program.
Now this is better than the fork() one because while using fork(), if didn't handled properly it could create a fork-bomb which would create processes recursively and will bomb your main memory. So its better to create a single process and have both functionality in it.
I am trying to do something a little weird here. I need to start a process, logcat, from a deamon that will run in the background and print to the terminal without taking control of stdin. It is for logging so ideally logcat will print log messages while still allowing the user to input standard commands and initialize programs from the shell. Here is the code for the daemon I have so far. The program, logcat, starts and shows log messages but I cannot enter any commands into stdin as it appears that the program has taken control of stdin.
int main ( int argc, char** argv, char** env )
{
int fd;
if ((fd = open("/dev/console", O_RDWR)) < 0) {
fd = open("/dev/null", O_RDWR);
}
printf("THIS IS A TEST\n");
dup2(1, fd);
dup2(2, fd);
pid_t childpid = fork();
if(childpid == -1) {
perror("Failed to fork, logcat not starting");
return 1;
}
if(childpid == 0) {
//this is the child, exec logcat
setsid();
int execReturn = execl("/system/bin/logcat", "logcat", (char *) 0);
} else {
//this is the parent do nothing
close(fd);
return 0;
}
close(fd);
return 0;
}
Thanks
The 'logcat' command seems to be for Android development - that might explain the odd location of the command.
The key operation that you must fix is to ensure that you close your current standard input (the terminal) and open /dev/null/ for the input device:
close(0);
if ((fd = open("/dev/null", O_RDONLY)) != 0)
...error - failed to open /dev/null!
This means that your daemonized child process will not read anything from the terminal.
What I think you want to do is:
Run your launcher program from a command line, which will have standard input, standard output and standard error connected to 'the terminal'.
Inside your program, you want to replace the standard input so it comes from /dev/null.
You want to leave standard output alone - you want logcat to write to the current standard output.
You probably want to leave standard error alone too.
At some point in the proceedings, you do your daemonization properly (borrowing the link from #bstpierre's answer), making sure that the terminal you are connected to is not your controlling terminal, so that interrupts and hangups sent to the terminal don't affect your daemon. The plumbing is simpler than what you have set up - you should deal with standard input and leave standard output and standard error unchanged (instead of changing the outputs and leaving the input unchanged).
Now, you might want the output to go to /dev/console; if so, then it is reasonable to revise the code to open /dev/console. However, it is not reasonable to fall back on /dev/null if you can't open /dev/console; your program should report an error and fail (because there is no point in having logcat writing to /dev/null!). Make sure you open the console with the O_NOCTTY flag so it does not become the controlling terminal for the daemon.
The final comment I'd make is:
Are you sure you want random text appearing over your terminal or console when it is in use for other things?
I don't much like it when that happens.
See also: SO 958249
How to Daemonize in Linux [dead link]
How to Daemonize in Linux [wayback machine archive of the above]
gist on github -- code taken from link above
Executive summary:
One of the things I keep running across is Linux daemons that don’t properly daemonize themselves. To properly daemonize, the following steps must be followed.
The fork() call is used to create a separate process.
The setsid() call is used to detach the process from the parent (normally a shell).
The file mask should be reset.
The current directory should be changed to something benign.
The standard files (stdin,stdout and stderr) need to be reopened.
Failure to do any of these steps will lead to a daemon process that can misbehave. The typical symptoms are as follows.
Starting the daemon and then logging out will cause the terminal to hang. This is particularly nasty with ssh.
The directory from which the daemon was launched remains locked.
Spurious output appears in the shell from which the daemon was started.
There is special purposed function for this in glibc:
#include <unistd.h>
...
/* We are in the parent, yet */
daemon(0,0);
/* Now we are in the child */
...
More details here http://linux.die.net/man/3/daemon