ÃÑ ÆäÀÌÁö ¼ö : 3224
![]()
|
Facebook Joinc ±×·ì
Joinc QA »çÀÌÆ®
![]()
Tweet
joinc´Â Firefox¿Í chrome¿¡¼ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù. ¼Ò°³
fork()´Â »õ·Î¿î ÀÚ½ÄÇÁ·Î¼¼½º¸¦ ½ÇÇà½Ã۱â À§Çؼ »ç¿ëÇϸç, ´Ù¼öÀÇ Å¬¶óÀÌ¾ðÆ®¸¦ µ¿½Ã¿¡ ó¸®Çϱâ À§Çؼ ÀÔÃâ·Â´ÙÁßÈ¿Í ÇÔ²² °¡Àå ³Î¸® »ç¿ëµÇ´Â ¹æ½ÄÀÌ´Ù.
ÀÌ ¹æ½ÄÀÇ ´ÜÁ¡À̶ó¸é fork()·Î »õ·Î¿î ÇÁ·Î¼¼½º¸¦ »ý¼º½ÃŰ´Â ÀÚü¿¡ ¸¹Àº ºñ¿ëÀÌ µé¾î°£´Ù´Â Á¡ÀÌ µÉ °ÍÀÌ´Ù. ÀÌ ¹®Á¦¸¦ ÇØ°áÇϱâ À§Çؼ Àû´çÇÑ ¼ö¸¸Å ÇÁ·Î¼¼½º¸¦ ¹Ì¸® ÇÒ´ç½ÃÄÑ ³õ°í, »õ·Î¿î ¿¬°áÀÌ µé¾î¿À¸é ÇÒ´çµÈ ÇÁ·Î¼¼½º¿¡ ¼ÒÄÏÀ» Àü´ÞÇØÁÖ´Â prefork¹æ½ÄÀ» »ç¿ëÇϱ⵵ ÇÑ´Ù. ÀÏÁ¾ÀÇ ÇÁ·Î¼¼½º Ç®À» ¸¸µé¾î¼ Ȱ¿ë ÇÏ´Â °ÍÀ¸·Î º¼ ¼ö ÀÖ´Ù. ÀÌ ¹®¼´Â prefork ¿¡ ´ëÇØ¼ ¼Ò°³ÇÑ´Ù.
´ÙÀ½°ú °°Àº Á¤º¸µéÀ» °¡Áö°í ÀÖ´Ù¸é ¹®¼ÀÇ Á¢±ÙÀÌ ½¬¿ï °ÍÀÌ´Ù. ¼ÒÄÏ Àü´Þ
prefork ±¸ÇöÀÇ ÇÙ½ÉÀº accept ÇÔ¼ö È£Ãâ ÈÄ ¸¸µé¾îÁø '¼ÒÄÏ ÁöÁ¤ ¹øÈ£'¸¦ ¾î¶»°Ô ÀÌ¹Ì ¸¸µé¾îÁ® ÀÖ´Â ÀÚ½Ä ÇÁ·Î¼¼½º¿¡ Àü´ÞÇÏ´À³Ä¿¡ ÀÖ´Ù. ´ÙÇàÈ÷ ÀÌ¿¡ ´ëÇÑ ÇØ¹ýÀº ³ª¿Í ÀÖ±ä Çѵ¥, ÇØ¹ý ÀÚü°¡ Á» ¸¶¹ýÀûÀÌ´Ù.
¼ÒÄÏ Àü´ÞÀº sendmsg ÇÔ¼ö·Î ÀÌ·ç¾îÁø´Ù. sendmsg ÇÔ¼ö´Â msghdr ±¸Á¶Ã¼·Î µ¥ÀÌÅ͸¦ Àü´ÞÇϴµ¥, msghdr ±¸Á¶Ã¼¿¡ Àü´ÞÇÒ ¼ÒÄÏ ÁöÁ¤ ¹øÈ£ Á¤º¸¸¦ Æ÷ÇÔÇÑ Á¦¾î Á¤º¸¸¦ ÇÔ²² ³Ñ±â´Â ¹æ½ÄÀ¸·Î ÀÌ·ç¾î Áø´Ù. ´ÙÀ½Àº ¼ÒÄÏ Àü´ÞÀ» À§Çؼ »ç¿ëÇÏ´Â ÇÔ¼öÀÎ write_fd ÀÌ´Ù. int write_fd(int fd, void *ptr, size_t nbytes, int sendfd) { struct msghdr msg; // ºÎ°¡ÀûÀ¸·Î ³Ñ±æ µ¥ÀÌÅÍ ±¸Á¶Ã¼ struct iovec iov[1]; union { struct cmsghdr cm; char control[CMSG_SPACE(sizeof(int))]; } control_un; // Á¦¾î Á¤º¸¸¦ Æ÷ÇÔÇÑ cmsghdr ±¸Á¶Ã¼ struct cmsghdr *cmptr; msg.msg_control = control_un.control; msg.msg_controllen = sizeof(control_un.control); // Á¦¾î Á¤º¸¸¦ ¼³Á¤ÇÑ´Ù. cmptr = CMSG_FIRSTHDR(&msg); cmptr->cmsg_len = CMSG_LEN(sizeof(int)); cmptr->cmsg_level = SOL_SOCKET; cmptr->cmsg_type = SCM_RIGHTS; // Àü¼ÛÇÒ ¼ÒÄÏ ÁöÁ¤ ¹øÈ£¸¦ º¹»çÇÑ´Ù. *((int *) CMSG_DATA(cmptr)) = sendfd; msg.msg_name = NULL; msg.msg_namelen = 0; // ±âŸ º¸³¾ µ¥ÀÌÅͰ¡ ÀÖ´Ù¸é ÇÔ²² Àü¼ÛÇÑ´Ù. iov[0].iov_base = ptr; iov[0].iov_len = nbytes; msg.msg_iov = iov; msg.msg_iovlen = 1; // sendmsg ÇÔ¼ö·Î µ¥ÀÌÅ͸¦ Àü¼ÛÇÑ´Ù. return(sendmsg(fd, &msg, 0)); }
´ÙÀ½Àº ¼ÒÄÏ ÁöÁ¤ ¹øÈ£¸¦ Àбâ À§ÇÑ ÇÔ¼ö read_fd·Î ÀÚ½Ä ÇÁ·Î¼¼½º¿¡¼ È£Ãâ ÇÑ´Ù. int read_fd(int fd, char *buf, size_t buflen) { int n; int recvfd; char ptr; struct iovec iov[1]; struct cmsghdr *cmptr; struct msghdr msg; union { struct cmsghdr cm; char control[CMSG_SPACE(sizeof(int))]; } control_un; // Á¦¾î Á¤º¸¸¦ ¼³Á¤ÇÑ´Ù. msg.msg_control = control_un.control; msg.msg_controllen = sizeof(control_un.control); msg.msg_name = NULL; msg.msg_namelen = 0; // ºÎ°¡ÀûÀ¸·Î Àоî¿Ã µ¥ÀÌÅÍ iov[0].iov_base = buf; iov[0].iov_len = buflen; msg.msg_iov = iov; msg.msg_iovlen = 1; if ( (n = recvmsg(fd, &msg, 0)) <= 0) { perror("recvmsg Error"); return -1; } cmptr = CMSG_FIRSTHDR(&msg); if ((cmptr == NULL)) { perror("CMSG ERROR\n"); return -1; } // Á¦¾î Á¤º¸¿¡¼ ¼ÒÄÏ ÁöÁ¤ ¹øÈ£¸¦ °¡Á®¿Í¼ ¹ÝȯÇÑ´Ù. recvfd = *((int *) CMSG_DATA(cmptr)); return recvfd; } Å×½ºÆ®¿¡ »ç¿ëÇÒ echo ¼¹ö#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define SA struct sockaddr
struct _SocketInfo
{
int pid;
int fd;
int status;
};
int write_fd(int fd, void *ptr, size_t nbytes, int sendfd);
int prefork_client(int fd);
int read_fd(int fd);
int main_server(int server_sockfd,
struct _SocketInfo *SInfo,
struct sockaddr_in clientaddr,
int preforknum);
int main(int argc, char **argv)
{
char buf_in[80];
int state;
int clilen;
int n,i,pid;
int preforknum;
int ppid;
int sv[2];
struct _SocketInfo *SocketArray;
int server_sockfd, client_sockfd;
struct sockaddr_in clientaddr, serveraddr;
if (argc != 2)
{
fprintf(stderr, "Usage: %s [prefork#]\n", argv[0]);
return 1;
}
preforknum = atoi(argv[1]);
if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("Error");
return 1;
}
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(8083);
bind(server_sockfd, (SA *)&serveraddr, sizeof(serveraddr));
if ((state = listen(server_sockfd, 5))<0)
{
perror("listen error: ");
exit(0);
}
if(preforknum > 10)
{
fprintf(stderr,"Max preforknum is 10\n");
exit(0);
}
ppid = getpid();
// Socket Infomation Array
SocketArray = (void *)malloc(sizeof(struct _SocketInfo)*preforknum);
memset((void *)SocketArray, 0x00, sizeof(struct _SocketInfo)*preforknum);
for (i = 0; i < preforknum; i++)
{
socketpair(AF_LOCAL, SOCK_STREAM, AF_LOCAL, sv);
pid = fork();
if (pid < 0)
{
perror("fork error");
exit(0);
}
if (pid == 0)
{
dup2(sv[0], 0);
close(sv[1]);
close(sv[0]);
close(server_sockfd);
prefork_client(0);
}
else
{
close(sv[0]);
SocketArray[i].pid = pid;
SocketArray[i].fd = sv[1];
SocketArray[i].status = 1;
}
}
main_server(server_sockfd, SocketArray, clientaddr, preforknum);
}
int write_fd(int fd, void *ptr, size_t nbytes, int sendfd)
{
struct msghdr msg;
struct iovec iov[1];
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
struct cmsghdr *cmptr;
msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control);
cmptr = CMSG_FIRSTHDR(&msg);
cmptr->cmsg_len = CMSG_LEN(sizeof(int));
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
*((int *) CMSG_DATA(cmptr)) = sendfd;
msg.msg_name = NULL;
msg.msg_namelen = 0;
iov[0].iov_base = ptr;
iov[0].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
return(sendmsg(fd, &msg, 0));
}
int read_fd(int fd)
{
int n;
int recvfd;
char ptr;
struct iovec iov[1];
struct cmsghdr *cmptr;
struct msghdr msg;
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control);
msg.msg_name = NULL;
msg.msg_namelen = 0;
iov[0].iov_base = (void *)&ptr;
iov[0].iov_len = 1;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
if ( (n = recvmsg(fd, &msg, 0)) <= 0)
{
perror("recvmsg Error");
return -1;
}
cmptr = CMSG_FIRSTHDR(&msg);
if ((cmptr == NULL))
{
perror("CMSG ERROR\n");
return -1;
}
recvfd = *((int *) CMSG_DATA(cmptr));
return recvfd;
}
int main_server(int server_sockfd,
struct _SocketInfo *SocketArray,
struct sockaddr_in clientaddr,
int preforknum)
{
int clilen;
int client_sockfd;
int i;
char ptr;
int n;
int maxfd;
fd_set readfds, allfds;
int data;
FD_ZERO(&readfds);
FD_SET(server_sockfd, &readfds);
for (i = 0; i < preforknum; i++)
{
FD_SET(SocketArray[i].fd, &readfds);
maxfd = SocketArray[i].fd;
printf("socketpair fd %d\n", maxfd);
}
printf("%d\n", maxfd+1);
allfds = readfds;
while(1)
{
readfds = allfds;
clilen = sizeof(clientaddr);
printf("select Wait\n");
n = select(maxfd + 1, &readfds, (fd_set *)0, (fd_set *)0, NULL);
printf("select Wait End %d\n", n);
if (n < 0) continue;
if (FD_ISSET(server_sockfd, &readfds))
{
printf("ACCEPT\n");
if ((client_sockfd = accept(server_sockfd, (SA *)&clientaddr, (size_t *)&clilen)) ==-1)
{
perror("accept error:");
close(client_sockfd);
}
else
{
for (i = 0; i < preforknum; i++)
{
if(SocketArray[i].status)
{
printf("SocketSend pid(%d) -> %d\n", SocketArray[i].pid, client_sockfd);
write_fd(SocketArray[i].fd, &ptr, 1, client_sockfd);
SocketArray[i].status = 0;
close(client_sockfd);
break;
}
}
if (i == preforknum)
{
fprintf(stderr, "max Client error\n");
close(client_sockfd);
}
}
}
for (i = 0; i < preforknum; i++)
{
if(FD_ISSET(SocketArray[i].fd, &readfds))
{
printf("OK Chield Data\n");
read(SocketArray[i].fd, (void *)&data, sizeof(data));
printf("(%d) : Read Data %d\n", SocketArray[i].fd, data);
if(data == 0)
{
SocketArray[i].status = 1;
}
}
}
}
}
int prefork_client(int fd)
{
int n;
char buf_in[80]={0x00,};
int sockfd;
int msg = 0;
printf("Child PID %d\n", getpid());
while(1)
{
sockfd = read_fd(fd);
for(;;)
{
if ((n = read(sockfd, buf_in, 79)) > 0)
{
write(sockfd, buf_in, strlen(buf_in));
}
else
{
printf("Client Socket Close\n");
write(fd, (void *)&msg, sizeof(msg));
close(sockfd);
break;
}
memset(buf_in, 0x00, sizeof(buf_in));
}
}
}
exec ÀÀ¿ë
fork(2)¹æ½Ä¿¡¼ ¼ÒÄÏÀü´ÞÀÌ ¼º°øÀûÀ¸·Î ÀÌ·ç¾îÁö´Â°É È®ÀÎÇß´Ù. ÀÌÁ¦ exec(2)¿¡¼µµ °¡´ÉÇÑÁö È®ÀÎÇØ º¸·Á ÇÑ´Ù. À§ÀÇ ÇÁ·Î±×·¥À» ¾à°£ ¼öÁ¤Çؼ Ŭ¶óÀ̾ðÆ®ÀÇ ¿¬°áÀ» acceptÇϰí prefork¸¦ ÇÏ´Â socketmain.c ÇÁ·Î±×·¥°ú preforkµÇ¾î¼ µ¥ÀÌÅ͸¦ ó¸®ÇÏ´Â prefork.c¶ó´Â ÇÁ·Î±×·¥À» ¸¸µé¾ú´Ù.
socketmain.c´Â À§ÀÇ fork ¹öÁ¯¿¡¼ ¾Æ·¡ÀÇ ¶óÀθ¸ ¼öÁ¤Çß´Ù. if (pid == 0)
{
dup2(sv[0], 0);
close(sv[1]);
close(sv[0]);
close(server_sockfd);
prefork_client(0);
}
¸¦
if (pid == 0)
{
dup2(sv[0], 0);
close(sv[1]);
close(sv[0]);
close(server_sockfd);
execl("./client", "client", NULL);
}
·Î
´ÙÀ½Àº prefork.c ·Î int prefork_client ÇÔ¼ö¸¦ ¾à°£ ¼öÁ¤Çؼ Àç ÀÛ¼ºÇß´Ù. #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/stat.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #define SA struct sockaddr int read_fd(int fd); int main(int argc, char **argv) { int n; char buf_in[80]={0x00,}; int sockfd; int msg = 0; printf("Child PID %d\n", getpid()); int fd = 0; while(1) { sockfd = read_fd(fd); for(;;) { if ((n = read(sockfd, buf_in, 79)) > 0) { write(sockfd, buf_in, strlen(buf_in)); } else { printf("Client Socket Close\n"); write(fd, (void *)&msg, sizeof(msg)); close(sockfd); break; } memset(buf_in, 0x00, sizeof(buf_in)); } } } int read_fd(int fd) { int n; int recvfd; char ptr; struct iovec iov[1]; struct cmsghdr *cmptr; struct msghdr msg; union { struct cmsghdr cm; char control[CMSG_SPACE(sizeof(int))]; } control_un; msg.msg_control = control_un.control; msg.msg_controllen = sizeof(control_un.control); msg.msg_name = NULL; msg.msg_namelen = 0; iov[0].iov_base = (void *)&ptr; iov[0].iov_len = 1; msg.msg_iov = iov; msg.msg_iovlen = 1; if ( (n = recvmsg(fd, &msg, 0)) <= 0) { perror("recvmsg Error"); return -1; } cmptr = CMSG_FIRSTHDR(&msg); if ((cmptr == NULL)) { perror("CMSG ERROR\n"); return -1; } recvfd = *((int *) CMSG_DATA(cmptr)); return recvfd; } |
|
|
EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù. |
|