svc_run() 메서드를 통해 들어오는 RPC를 수신 대기하는 자식 프로세스를 생성하는 클라이언트 프로세스가 있습니다. 내가해야 할 일은 부모로부터 그 자식 프로세스를 죽인 다음 자식 프로세스를 다시 fork하여 새로운 CLIENT *에 새로운 RPC 서버를 제공하는 것입니다.RPC 서비스 다시 시작
여기에 관련된 나의 코드의 비트 : 내 서버 코드에서
// Client Main
CLIENT* connectionToServer;
int pipe[2];
int childPID;
int parentPID;
static void usr2Signal()
{
ServerData sd;
clnt_destroy(connectionToServer);
(void) read(pipe[0], &sd, sizeof(sd));
// Kill child process.
kill(childPID, SIGTERM);
close(pipe[0]);
// RPC connection to the new server
CLIENT *newServerConn =
clnt_create(
sd.ip,
sd.programNum,
1,
"tcp");
if (!newServerConn)
{
// Connection error.
exit(1);
}
connectionToServer = newServerConn;
// Respawn child process.
if (pipe(pipe) == -1)
{
// Pipe error.
exit(2);
}
childPID = fork();
if (childPID == -1)
{
// Fork error.
exit(3);
}
if (childPID == 0)
{
// child closes read pipe and listens for RPCs.
close(pipe[0]);
parentPID = getppid();
svc_run();
}
else
{
// parent closes write pipe and returns to event loop.
close(pipe[1]);
}
}
int main(int argc, char *argv[])
{
/* Some initialization code */
transp = svctcp_create(RPC_ANYSOCK, 0, 0);
if (transp == NULL) {
// TCP connection error.
exit(1);
}
if (!svc_register(transp, /*other RPC program args*/, IPPROTO_TCP))
{
// RPC register error
exit(1);
}
connectionToServer = clnt_create(
192.168.x.xxx, // Server IP.
0x20000123, // Server RPC Program Number
1, // RPC Version
"tcp");
if (!connectionToServer)
{
// Connection error
exit(1);
}
// Spawn child process first time.
if (pipe(pipe) == -1)
{
// Pipe error
exit(1);
}
childPID = fork();
if (childPID == -1)
{
// Fork error.
exit(1);
}
if (childPID == 0)
{
// Close child's read pipe.
close(pipe[0]);
parentPID = getppid();
// Listen for incoming RPCs.
svc_run();
exit (1);
}
/* Signal/Communication Code */
// Close parent write pipe.
close(pipe[1]);
// Parent runs in event loop infinitely until a signal is sent.
eventLoop();
cleanup();
}
나는 새 연결을 시작하는 서비스 호출이있다. 이 호출은 서버의 다른 작업에 의해 호출됩니다.
// Server Services
void newserverconnection_1_svc(int *unused, struct svc_req *s)
{
// This service is defined in the server code
ServerData sd;
/* Fill sd with data:
Target IP: 192.168.a.aaa
RPC Program Number: 0x20000321
... other data
*/
connecttonewserver_1(&sd, connectionToServer); // A client service.
}
다시 내 클라이언트에서 나는 다음과 같은 서비스를 : 나는 새로운 연결을 시작할 때까지
// Client Service
void connecttonewserver_1_svc(ServerData *sd, struct svc_req *s)
{
// Send the new server connection data to the parent client processs
// via the pipe and signal the parent.
write(pipe[1], sd, sizeof(sd));
kill(parentPID, SIGUSR2);
}
내 문제는, 모든 것이 잘 실행됩니다. 내 오류 섹션 중 하나에 들어 가지 않지만 새 연결을 설정 한 후 약 5 초가 지나면 클라이언트가 응답하지 않게됩니다. 그것은 크래시가 발생하지 않고 자식 프로세스가 여전히 살아있는 것처럼 보입니다. 그러나 마우스의 클릭에 의해 부모 이벤트 루프에 정의 된 이벤트가 트리거 될 때 클라이언트는 더 이상 RPC를 수신하지 않거나 인쇄 문을 표시하지 않습니다. 자식 프로세스에 대해이 새로운 RPC 루프를 생성하기 위해 약간 잘못된 것이 있습니다. 그러나 나는 무엇을 볼 수 없습니다. 어떤 아이디어?
'connectionToServer'에 할당되고'usr2Signal()'에서 사용 된 메모리는 해제되지 않습니다. 그런 다음'main()'에서 다시 사용합니다. –
그래서 내 메인이 한 번 실행되고 실행하는 첫 번째 일이라고 생각합니다. main에있는 fork 후에 자식 프로세스는 자식 프로세스가 종료 될 때까지 "svc_run()"을 실행합니다. 부모는 eventLoop을 계속 수행하고 "usr2Signal"을 트리거하는 신호를 제외하고 무기한으로 실행합니다. 메인에서 아무 것도 메인에서 "connectionToServer"의 사용법을보고 있습니까? – MrJman006
또한 "usr2Signal"에서 "clnt_destroy"가 할당 된 메모리를 정리하지 않습니까? – MrJman006