我用C语言编写的服务器有一个奇怪的问题。
我有一个函数来处理连接到我的服务器的每个客户端,因此该函数为服务器接收的每个连接调用fork()。
问题是我在client-fork
内部有其他的forks,它们应该在我创建的文件中写一个exec()
的输出.I dup2()
该文件的描述符带有stdout这样在第二个子进程(具有exec()
调用的进程)之后,可以从父进程内的文件中读取输出。
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <fcntl.h>
#define PORT 2021
extern int errno;
void signal_handler( int sig )
{
printf("[Server]Cought signal SIGCHLD\n");
while( waitpid(-1, NULL, WNOHANG) > 0 )
{
}
}
int TreatClient(int clientSocket, int nr)
{
int pid1,wait1;
if ((pid1 = fork()) == -1)
{
printf("eroare pid");
exit(1);
}
if(pid1 == 0) // treat client
{
printf("START TREAT CLIENT!\n");
nr++;
int saved_stdout;
char filename[3];
snprintf(filename, 3,"%d",nr);
int pid2,wait2;
saved_stdout = dup(1);
if ((pid2 = fork()) == -1)
{
printf("eroare pid");
exit(1);
}
if(pid2 == 0)
{
printf("START DUP child!\n");
int fd = open("fisier",O_CREAT|O_RDWR,00700);
dup2(fd,1);
printf("child 2 !\n");
close(fd);
return 1;
}
else
{
int fil;
char chara;
wait(&wait2);
dup2(saved_stdout,1);
close(saved_stdout);
fil = open("fisier",O_RDONLY,00700);
while(read(fil,&chara,1)!=-1 && chara != '\n') printf("%c",chara);
printf("\nEND PARENT dup !\n");
}
printf("TREAT CLIENT END!\n");
return 1;
}
else
{
wait(&wait1);
printf("END MAIN!\n");
}
return 1;
} /* while */
return 0;
return 1;
}
int main()
{
struct sockaddr_in server;
struct sockaddr_in from;
char msg[100];
char rply[100]=" ";
int sd;
int on, status, nr = 0;
if( signal(SIGCHLD, signal_handler) < 0 )
{
printf("[Server]Signal Error : %d !\n", errno);
exit(-5);
}
if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
perror ("[server]Socket Error !\n");
return errno;
}
on = 1;
status = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof(on));
if ( status == -1 )
{
printf("[server]Setsockopt() Error : %d !\n", errno);
exit(-1);
}
bzero (&server, sizeof (server));
bzero (&from, sizeof (from));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl (INADDR_ANY);
server.sin_port = htons (PORT);
if (bind (sd, (struct sockaddr *) &server, sizeof (struct sockaddr)) == -1)
{
printf("[server]Bind Error : %d!\n", errno);
exit(-2);
}
if (listen (sd, 5) == -1)
{
printf ("[server]Listen Error : %d!\n", errno);
exit(-3);
}
///////////////////////////////////////////////////////////////////////////////////////////
/* client-iteration*/
while (1)
{
int client;
int length = sizeof (from);
printf ("[server]Waiting at port %d...\n",PORT);
fflush (stdout);
client = accept (sd, (struct sockaddr *) &from, &length);
nr++;
if (client < 0)
{
printf ("[server]Accept Error : %d!\n", errno);
continue;
}
printf("[server]Client number %d connected\n", nr);
TreatClient(client, nr);
return 1;
}
所需的输出与此类似:
[server]Waiting at port 2021...
[server]Client number 1 connected
START TREAT CLIENT!
START DUP child!
[Server]Cought signal SIGCHLD
child 2 !
END PARENT dup !
TREAT CLIENT END!
[Server]Cought signal SIGCHLD
END MAIN!
代码不会产生所需的输出。它在DUP2之后变得卡住,其余的输出被重定向到文件。但是,如果我用功能块替换TreatClient(client, nr);
行,代码就可以正常工作。为什么会这样?另一个奇怪的问题是消息[server]Waiting at port 2021...
也打印在文件中,而不是打印在屏幕上。
答案 0 :(得分:1)
当第二个孩子完成时,它应该exit
而不是返回。