Indra
Indra

Reputation: 1

I have to perform a socket communication between 2 processes where one of them is a daemon

I have an application running which is the main app, and I want to create a daemon which can communicate with the main application to and fro , such that both can act as a server and a client.

Server Code:

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

}

Client Code::

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;
}

If I don't daemonize the client code then it works fine and communication had been established but the moment I call the API daemonize() and daemonize this process then server application does not recieve any communication from the client code.

    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

What am I missing out here ?

Any help on this would be highly appreciated..

Upvotes: 0

Views: 93

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409166

You open the socket connection in the client before you call the daemonize which closes all descriptors including your socket.

Open the socket connection after you "daemonize" the client process.


You should add more error checking, that actually prints the error you get. Both the send and recv calls in the client would return -1 and set errno appropriately which would have told you this.

Also unless you need to set special flags, I recommend you use write and read instead of send and recv.

Upvotes: 3

Related Questions