C 我必须在两个进程之间执行套接字通信,其中一个进程是守护进程

C 我必须在两个进程之间执行套接字通信,其中一个进程是守护进程,c,multithreading,sockets,process,C,Multithreading,Sockets,Process,我有一个正在运行的应用程序,它是主应用程序,我想创建一个守护进程,可以与主应用程序来回通信,这样两者都可以充当服务器和客户端 服务器代码: pthread_t t1; pthread_t t2; int main() { int sockfd;//to create socket int newsockfd;//to accept connection pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstac

我有一个正在运行的应用程序,它是主应用程序,我想创建一个守护进程,可以与主应用程序来回通信,这样两者都可以充当服务器和客户端

服务器代码:

pthread_t t1;
pthread_t t2;

int main()
{
int sockfd;//to create socket
int newsockfd;//to accept connection
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr,1024*1024);

int status;
printf("Creating Threads1::\n");
status=pthread_create(&t1,&attr,(void*)&call_server_thread,NULL);
if(status!=0){
     printf("Failed to create Thread1 with Status:%d\n",status);
}

/*
printf("Creating Threads2::\n");
status=pthread_create(&t2,&attr,(void*)&call_client_thread,NULL);
if(status!=0){
    printf("Failed to create Thread2 with Status:%d\n",status);
}
*/

pthread_join(t1,NULL);
//pthread_join(t2,NULL);

return 0;

}

void call_server_thread()
{
//create socket
int sockfd;//to create socket
int newsockfd;//to accept connection

struct sockaddr_in serverAddress;//server receive on this address
struct sockaddr_in clientAddress;//server sends to client on this address

int n,exec_sec=3;
char msg[MAXSZ];
int clientAddressLength;
int pid;
sockfd=socket(AF_INET,SOCK_STREAM,0);
//initialize the socket addresses
memset(&serverAddress,0,sizeof(serverAddress));
serverAddress.sin_family=AF_INET;
serverAddress.sin_addr.s_addr=htonl(INADDR_ANY);
serverAddress.sin_port=htons(PORT);

//bind the socket with the server address and port
bind(sockfd,(struct sockaddr *)&serverAddress, sizeof(serverAddress));

//listen for connection from client
listen(sockfd,5);

while(1)
{
    //parent process waiting to accept a new connection
    printf("\n*****server waiting for new client connection:*****\n");
    clientAddressLength=sizeof(clientAddress);
    newsockfd=accept(sockfd,(struct 
    sockaddr*)&clientAddress,&clientAddressLength);
    // printf("connected to client: 
    %d\n",inet_ntoa(clientAddress.sin_addr));

    //child process is created for serving each new clients
    pid=fork();
    if(pid==0)//child process rec and send
    {
        //rceive from client
        while(1)
        {
            n=recv(newsockfd,msg,MAXSZ,0);
            if(n==0)
            {
                close(newsockfd);
                break;
            }
            msg[n]='\0';
            send(newsockfd,msg,n,0);

            printf("Receive and set:%s\n",msg);
            printf("Server Thread will sleep for %d seconds\n",exec_sec);
            sleep(exec_sec);
        }//close interior while
        exit(0);
    }
    else
    {
        close(newsockfd);//sock is closed BY PARENT
    }
    printf("Server Thread will sleep for %d seconds\n",exec_sec);
    sleep(exec_sec);
}//close exterior while

}
客户端代码::

int daemonize(char* name, char* path, char* outfile, char* errfile, char* 
infile )
{
if(!path) { path="~/CODE/PLATFORM/"; }
if(!name) { name="medaemon"; }
if(!infile) { infile="/dev/null"; }
if(!outfile) { outfile="/dev/null"; }
if(!errfile) { errfile="/dev/null"; }
//printf("%s %s %s %s\n",name,path,outfile,infile);
pid_t child;
//fork, detach from process group leader
if( (child=fork())<0 ) { //failed fork
    fprintf(stderr,"error: failed fork\n");
    exit(EXIT_FAILURE);
}
if (child>0) { //parent
    exit(EXIT_SUCCESS);
}
if( setsid()<0 ) { //failed to become session leader
    fprintf(stderr,"error: failed setsid\n");
    exit(EXIT_FAILURE);
}

//catch/ignore signals
signal(SIGCHLD,SIG_IGN);
signal(SIGHUP,SIG_IGN);

//fork second time
if ( (child=fork())<0) { //failed fork
    fprintf(stderr,"error: failed fork\n");
    exit(EXIT_FAILURE);
}
if( child>0 ) { //parent
    exit(EXIT_SUCCESS);
}

//new file permissions
umask(0);
//change to path directory
chdir(path);

//Close all open file descriptors
int fd;
for( fd=sysconf(_SC_OPEN_MAX); fd>0; --fd )
{
    close(fd);
}

//reopen stdin, stdout, stderr
stdin=fopen(infile,"r");   //fd=0
stdout=fopen(outfile,"w+");  //fd=1
stderr=fopen(errfile,"w+");  //fd=2

//open syslog
openlog(name,LOG_PID,LOG_DAEMON);
return(0);
}



int main()
{
int sockfd;//to create socket

struct sockaddr_in serverAddress;//client will connect on this

int n,res;
char msg1[MAXSZ];
char msg2[MAXSZ];

//create socket
sockfd=socket(AF_INET,SOCK_STREAM,0);
//initialize the socket addresses
memset(&serverAddress,0,sizeof(serverAddress));
serverAddress.sin_family=AF_INET;
serverAddress.sin_addr.s_addr=inet_addr(SERVER_IP);
serverAddress.sin_port=htons(PORT);

//client  connect to server on port
connect(sockfd,(struct sockaddr *)&serverAddress,sizeof(serverAddress));
//send to sever and receive from server

if( (res=daemonize("mydaemon","~/CODE/PLATFORM",NULL,NULL,NULL)) != 0 ) {
    fprintf(stderr,"error: daemonize failed\n");
    exit(EXIT_FAILURE);
}

while(1)
{
    printf("\nEnter message to send to server:\n");
    //fgets(msg1,MAXSZ,stdin);

    memcpy(msg1,"INDRA",strlen("INDRA"));

    if(msg1[0]=='#')
        break;

    n=strlen(msg1)+1;
    send(sockfd,msg1,n,0);

    n=recv(sockfd,msg2,MAXSZ,0);

    printf("Receive message from  server::%s\n",msg2);
    sleep(3);
}

return 0;
}
我错过了什么


在此方面的任何帮助都将不胜感激。

在调用关闭所有描述符(包括套接字)的
守护进程之前,请先在客户端中打开套接字连接

在“守护”客户端进程之后打开套接字连接


您应该添加更多的错误检查,这实际上会打印您得到的错误。客户端中的
send
recv
调用都会返回
-1
,并正确设置
errno
,这会告诉您这一点


另外,除非您需要设置特殊标志,否则我建议您使用
write
read
而不是
send
recv
,在调用关闭所有描述符(包括套接字)的
daemonize之前,在客户端中打开套接字连接

在“守护”客户端进程之后打开套接字连接


您应该添加更多的错误检查,这实际上会打印您得到的错误。客户端中的
send
recv
调用都会返回
-1
,并正确设置
errno
,这会告诉您这一点


另外,除非您需要设置特殊标志,否则我建议您使用
write
read
而不是
send
recv

谢谢您的审阅。我忽略了这个错误。我颠倒了套接字创建顺序,但仍然存在相同的问题,服务器无法获取daemonized客户端。这里的主要问题是守护进程,因此最好找到解决方案。因为没有守护进程,它可以正常工作。在守护客户端代码时,我注释掉了下面的代码部分。这甚至关闭了服务器套接字文件描述符。现在它工作得很顺利/*对于(fd=sysconf(_SC_OPEN_MAX);fd>0;--fd){close(fd)}*/感谢您的审阅。我忽略了这个错误。我颠倒了套接字创建顺序,但仍然存在相同的问题,服务器无法获取daemonized客户端。这里的主要问题是守护进程,因此最好找到解决方案。因为没有守护进程,它可以正常工作。在守护客户端代码时,我注释掉了下面的代码部分。这甚至关闭了服务器套接字文件描述符。现在它工作得很顺利/*对于(fd=sysconf(_SC_OPEN_MAX);fd>0;--fd){close(fd);}*/格式化/缩进………'n=recv(newsockfd,msg,MAXSZ,0);'后跟'msg[n]='\0';'如果接收到所有MAXSZ字符,则为越界写入,因此为UB。缓冲区大小过大(MAXSZ+1),或recv大小过小(MAXSZ-1)。格式化/缩进………'n=recv(newsockfd,msg,MAXSZ,0);'后跟'msg[n]='\0';'如果接收到所有MAXSZ字符,则为越界写入,因此为UB。缓冲区尺寸过大(MAXSZ+1),或recv尺寸过小(MAXSZ-1)。
    without daemon output:

    [ibanerje@bri-up-swe-04 Process]$ ./a.out
    Creating Threads1::

    *****server waiting for new client connection:*****
    Server Thread will sleep for 3 seconds
    Receive and set:INDRA
    Server Thread will sleep for 3 seconds

    *****server waiting for new client connection:*****
    Receive and set:INDRA
    Server Thread will sleep for 3 seconds
    Receive and set:INDRA
    Server Thread will sleep for 3 seconds
    Receive and set:INDRA
    Server Thread will sleep for 3 seconds
    Receive and set:INDRA

with daemon  output ::

Creating Threads1::

*****server waiting for new client connection:*****
Server Thread will sleep for 3 seconds

*****server waiting for new client connection:*****
^C