기본 응용 프로그램이 실행되는 응용 프로그램을 가지고 있고 주 응용 프로그램과주고받을 수있는 데몬을 만들고 싶습니다. 둘 다 서버와 클라이언트로 작동 할 수 있습니다.그 중 하나가 데몬 인 2 개의 프로세스 사이에서 소켓 통신을 수행해야합니다.
서버 코드 :
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:
[[email protected] 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
를 호출하기 전에 이것에 어떤 도움을 매우 극명하게 될 것이다
..
서식 지정/들여 쓰기 ............ – ThingyWotsit
'n = recv (newsockfd, msg, MAXSZ, 0);' 'msg [n] ='\ 0 ';' 모든 MAXSZ 문자가 수신되면 범위를 벗어난 쓰기이므로 UB가됩니다. 버퍼를 오버 사이즈 (MAXSZ + 1)하거나 크기를 줄입니다 (MAXSZ-1). – ThingyWotsit