socket 프로그램에서 풀리지 않는 문제가 있습니다. 제발 도와 주십시요...

k2ufo의 이미지

소켓 프로그램을 작성하고 있습니다. socket의 서버쪽에서 fork를 합니다.
그리고 pid를 검사하여 차일드 프로세스면 execlp를 수행합니다. execlp를 수행하면서
파라메터로 소켓의 socket file desciptor를 넘겨 줌니다.

fromlen = sizeof(struct from);
if ( (ns = accept(s, (struct sockaddr*)&from, (int*)&fromlen)) < 0 ) {
if ( errno == EINTR ) continue;
printf("new socket accept error...\n);
exit(1);
}

...

if ( (pid = fork ()) < 0 ) {
printf("fork error\n");
} else
if ( pid == 0 ) {
close(s);
sprintf(socket_fd, "%d", ns);
execlp('/socket/fork_server', 'fork_server', socket_fd, (char *)NULL);
exit(0);
}

이렇게 넘긴 socket file desciptor를 통해서 fork 후 대체 된 프로그램에서 넘겨 받은
socket file desciptor를 통해서 어떻게 읽어야 하는지 도대체 않되는군요.
처음에는 recv,read,recvmsg/send,write/sendmsg 등을 사용해 보았지만 모두 않됩니다.
어찌해야 되는지 전혀 감이 오지 않습니다. 몇일 동안 헤메고 있습니다.
이렇게 설계를 할 수 밖에 없는 이유가 있습니다. 부디 알고 계시는 분 계시면 조언 좀 부탁드림니다.
샘플도 좋구요. 도와 주십시요.

꼭 부탁 드리겠습니다...

그럼...

panda005의 이미지

위의 예제에서 보시면,
부모 프로그램에서 소켓 생성해서 리슨하다가 어셉트되면
자식 프로세스를 포크해서 프로그램을 수행하는 구조인 것 같은데...
자식 프로세스를 보면
execlp를 이용해서 '/socket/fork_server'라는 프로세스를 실행합니다.
여기서 잠깐 exec계열 명령의 특성을 man에서 찾아보면

<span>영문</span>
The  exec  family of functions shall replace the current process image with a new process image. The new image shall be constructed from a regular, executable file called the new process image file. There shall be no return from a successful exec, because the calling process image is overlaid by the new process image.
<hr class="bb-hr" />
<span>한글</span>
exec 함수 계열은 현재 프로세스 이미지를 새로운 프로세스 이미지로 바꾼다. 이 매뉴얼에 기술된 함수들은 execve(2) 함수의 전위들이다. (현재 프로세스의 대체에 관한 세부적인 정보를 원하면 execve 매뉴얼 페이지를 참고해라.) 

입니다. 따라서 새로 실행시킨 fork_server의 이미지가 기존에 부모에게 물려받은 프로세스 이미지를 대체하게 되어서, 부모가 미리 열어 놓은 소켓이며 fd며 등등을 전혀 사용하지 못하게 되는 것입니다.

위와 같은 로직으로 수행하시려면, fork_server를 별도의 바이너리로 짜서 exec로 돌리지 마시고,
함수로 구현해서 자식 프로세스에서 exec대신에 함수 콜을 하도록 수정하시면 될 듯 합니다.

k2ufo의 이미지

먼저 감사 드림니다.

저도 처음에는 그렇게 하려고 했습니다. 그러나 IPC 통신을 하기 위한 모쥴과 충돌이 나서 fork 후
차일드 프로세스가 종료가 되지 않습니다. 차일드 프로세스가 종료하기 위해서 여러가지 방법을 써 보았지만
역시나 충돌을 일으킵니다. 그래서 이런 저런 방법을 찾다가 이런식으로 처리가 가능하다는 이야기를 들었습니다.
실제 그렇게 쓰고 있다고 하는데 저는 실력이 딸려서 도저히 방법을 못찾겠네요... 쩝...

좀 도와 주십시요...

그럼 수고하십시요...

panda005의 이미지

흠...
좀 막연한데요.
ipc 프로그래밍을 많이 하지를 않아서
그런 경우를 겪어본 적은 없거든요.
shm 쓰시나보죠?

보안상 허용 가능하다면 관련 부분 소스를 조금 더 보여주실 수는 없을까요?
아니면 panda0055@gmail.com으로 보내주셔도 되구요...

k2ufo의 이미지

먼저 panda005님깨 감사 드림니다. 정성들여 답해 주셔서 정말 감사드림니다.
새해 복 많이 받으십시요... ㅎ

fork된 차일드 프로세스에서 sendmsg와 recvmsg를 쓰면 되는데 제가 그만 정신을
못차려서 테스트 시, 실수를 했네요. 먼 생각을 했는지 말입니다... 쩝

전역 변수로 (식성에 따라서...)
char rbf[1024];
char sbf[1024];
struct msghdr msg;
struct iovec iov;

int send_msg(int ns, int *pass_fd) /* ns -> 부모 프로세스로 넘겨 받은 socket file desciptor : execlp에서 arg로 */
{
struct sockaddr_in sin;
int rv;

iov.iov_base = (void *)&sbf; /* send buffer : sbf */
iov.iov_len = sizeof(sbf);

msg.msg_name = &sin;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_iov = (struct iovec *)&iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
rv = sendmsg(ns, &msg, 0);
if( rv == -1) {
printf("sendmsg error\n");
exit(1);
}
return 0;
}

recv_msg(int ns, int *peer_fd) /* ns -> 부모 프로세스로 넘겨 받은 socket file desciptor : execlp에서 arg로 */
{
struct sockaddr_in sin;
int rv;

iov.iov_base = (void *)rbf; /* recv buffer : rbf */
iov.iov_len = sizeof(rbf);

msg.msg_name = &sin;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;

rv = recvmsg(ns, &msg, 0);
if( rv < 0 ) {
printf("recvmsg errno: %d\n", errno);
*peer_fd = -1;
return;
}
return ;
}

위 두 함수를 호출하면 됩니다...
수고하십시요...

panda005의 이미지

해결되셨다니 축하드려요 ^^
새해엔 하는 모든 일이 잘 되시길~

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.