gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 06:56:15 24 4
gpt4 key购买 nike

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

服务器代码:

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

如果我不 daemonize 客户端代码,那么它可以正常工作并且已经建立了通信,但是当我调用 API daemonize()daemonize 时 此过程然后服务器应用程序不会收到来自客户端代码的任何通信。

    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

我在这里错过了什么?

如有任何帮助,我们将不胜感激..

最佳答案

在调用 daemonize 之前,您在客户端打开套接字连接,它会关闭所有描述符,包括您的套接字。

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


你应该添加更多的错误检查,实际打印你得到的错误。客户端中的 sendrecv 调用都会返回 -1 并适本地设置 errno 这会告诉你这个。

此外,除非您需要设置特殊标志,否则我建议您使用writeread 而不是sendrecv.

关于c - 我必须在两个进程之间执行套接字通信,其中一个是守护进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44105540/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com