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