2008년 10월 8일 수요일
2008년 8월 1일 금요일
Unix Domain Socket
Unix Domain Socket(이하 UDS) 는 socket API를 수정없이 이용며,
port 기반의 Inernet Domain Socket에 비해서 로컬 시스템의 파일시스템을
이용해서 내부프로세스간의 통신을 위해 사용한다는 점이 다르다고 할수 있다.
ls 를 이용해서 통신을 위해서 만들어진 파일을 보면 다음과 같은 모습을
보인다.
[yundream@localhost tmp]$ ls -al
srwx------ 1 root nobody 0 12월 14 21:16 .fam_socket
보면 파일타입에 "s" 가 붙어 있는걸 알수 있으며, 파일사이즈가 0으로 되어 있는
걸 알수 있다. 왜냐하면 FIFO와 마찬가지로 메시지가 파일로 쌓이지 않고
커널로 전달되어서 커널에서 처리하기 때문이다.
파일을 통해서 통신을 하며, 커널내부에서 메시지를 관리한다는 점에서
FIFO와 매우 유사한면을 보여주지만, FIFO와는 달리 양방향 통신이 가능하다는
특징을 가지고 있다. 그러므로 다중의 클라이언트를 받아들이는 서버/클라이언트
모델을 만들기가 매우 쉽다.
또한 Inet 소켓을 통한 외부통신에 비해서 2배 이상의 효율을 보여준다라는
장점을 가지고 있다.
많은 경우 약간 복잡한 내부프로세스간 통신을 해야된다고 했을때 UDS을 많이
사용한다. INET 계층에서의 통신이 TCP/IP 4계층을 모두 거치는것과는
다르게, UDS 은 어플리케이션 계층에서 TCP 계층까지만 메시지가 전달되고,
다시 곧바로 어플리케이션 계층으로 메시지가 올라가게 된다. TCP/IP 계층에 대한
자세한 내용은 TCP/IP 개요(2)를 참고 하기 바란다.
위에서 INET 소켓보다 2배이상의 효율을 가진다고 했는데,
4계층의 레이어를 모두 거쳐야하는 INET 소켓에 비해서 단지 2개의 레이어만
사용한다는 점도 그 이유중 하나로 작용한다.
쏘쓰 코드는 다중연결서버 만들기(1)의 zipcode_multi.c 와
셈플로 알아보는 소켓프로그래밍(1)의 zipcode_cli.c 를 사용하도록할것이다.
예제: zipcode_local.c
1.
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
int server_sockfd, client_sockfd;
int state, client_len;
pid_t pid;
FILE *fp;
struct sockaddr_un clientaddr, serveraddr;
char buf[255];
char line[255];
if (argc != 2)
{
printf("Usage : ./zipcode [file_name]\n");
printf("예 : ./zipcode /tmp/mysocket\n");
exit(0);
}
memset(line, '0', 255);
state = 0;
if (access(argv[1], F_OK) == 0)
{
unlink(argv[1]);
}
// 주소 파일을 읽어들인다.
client_len = sizeof(clientaddr);
if((fp = fopen("zipcode.txt", "r")) == NULL)
{
perror("file open error : ");
exit(0);
}
// internet 기반의 스트림 소켓을 만들도록 한다.
if ((server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
{
perror("socket error : ");
exit(0);
}
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sun_family = AF_UNIX;
strcpy(serveraddr.sun_path, argv[1]);
state = bind(server_sockfd , (struct sockaddr *)&serveraddr,
sizeof(serveraddr));
if (state == -1)
{
perror("bind error : ");
exit(0);
}
state = listen(server_sockfd, 5);
if (state == -1)
{
perror("listen error : ");
exit(0);
}
printf("accept : \n");
while(1)
{
client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr,
&client_len);
printf("test test\n");
pid = fork();
if (pid == 0)
{
if (client_sockfd == -1)
{
perror("Accept error : ");
exit(0);
}
while(1)
{
memset(buf, '0', 255);
if (read(client_sockfd, buf, 255) <= 0)
{
close(client_sockfd);
fclose(fp);
exit(0);
}
if (strncmp(buf, "quit",4) == 0)
{
write(client_sockfd, "bye bye\n", 8);
close(client_sockfd);
fclose(fp);
break;
}
while(fgets(line,255,fp) != NULL)
{
if (strstr(line, buf) != NULL)
write(client_sockfd, line, 255);
memset(line, '0', 255);
}
write(client_sockfd, "end", 255);
printf("send end\n");
rewind(fp);
}
}
}
close(client_sockfd);
}
}
다음은 클라이언트 프로그램이다.
예제: zipcode_cli_local.c
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
int client_len;
int client_sockfd;
FILE *fp_in;
char buf_in[255];
char buf_get[255];
struct sockaddr_un clientaddr;
if (argc != 2)
{
printf("Usage : ./zipcode_cl [file_name]\n");
printf("예 : ./zipcode_cl /tmp/mysocket\n");
exit(0);
}
client_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (client_sockfd == -1)
{
perror("error : ");
exit(0);
}
bzero(&clientaddr, sizeof(clientaddr));
clientaddr.sun_family = AF_UNIX;
strcpy(clientaddr.sun_path, argv[1]);
client_len = sizeof(clientaddr);
if (connect(client_sockfd, (struct sockaddr *)&clientaddr, client_len) < 0)
{
perror("Connect error: ");
exit(0);
}
while(1)
{
printf("지역이름 입력 : ");
fgets(buf_in, 255,stdin);
buf_in[strlen(buf_in) - 1] = '0';
write(client_sockfd, buf_in, 255);
if (strncmp(buf_in, "quit", 4) == 0)
{
close(client_sockfd);
exit(0);
}
while(1)
{
read(client_sockfd, buf_get, 255);
if (strncmp(buf_get, "end", 3) == 0)
break;
printf("%s", buf_get);
}
}
close(client_sockfd);
exit(0);
}
기존의 INET 버젼의 프로그램과 비교해 보면 고작 3줄 정도만 수정되었음을
알수 있을것이다. 단지 소켓 구조체가 sockaddr_un 으로 바뀌고,
AF_INET 대신 AF_UNIX 를 그리고 port 번호대신에 파일명을 사용했음을
알수 있다.
나머지의 모든 코드는 INET 코드와 완전히 같다. 그러므로
Unix Domain Socket 를 사용하면 Inet Domain Socket 와 코드 일관성을
유지할수 있으며, 동일한 기술을 사용해서 프로그래밍을 할수 있다.
또한 다른 대부분의 IPC 설비들이, 범용적으로 사용하기에는 부족한 여러가지
단점들을 가진반면(단방향 이거나, 읽기만 가능하다거나, 제어하기가 어려운)
UDS는 매우 범용적인 IPC 로써 사용가능하다라는 장점을 가지고 있다.
실제로 X 서버 같은경우에 외부에서의 접근시에는 INET 연결을 내부에서의
연결을 위해서는 UDS 를 사용한다. 이밖에도 mysql, pgsql, KDE, Gnome 과 같은
대부분의 서버프로그램이 내부통신을 위해서 UDS 를 사용한다.
port 기반의 Inernet Domain Socket에 비해서 로컬 시스템의 파일시스템을
이용해서 내부프로세스간의 통신을 위해 사용한다는 점이 다르다고 할수 있다.
ls 를 이용해서 통신을 위해서 만들어진 파일을 보면 다음과 같은 모습을
보인다.
[yundream@localhost tmp]$ ls -al
srwx------ 1 root nobody 0 12월 14 21:16 .fam_socket
보면 파일타입에 "s" 가 붙어 있는걸 알수 있으며, 파일사이즈가 0으로 되어 있는
걸 알수 있다. 왜냐하면 FIFO와 마찬가지로 메시지가 파일로 쌓이지 않고
커널로 전달되어서 커널에서 처리하기 때문이다.
파일을 통해서 통신을 하며, 커널내부에서 메시지를 관리한다는 점에서
FIFO와 매우 유사한면을 보여주지만, FIFO와는 달리 양방향 통신이 가능하다는
특징을 가지고 있다. 그러므로 다중의 클라이언트를 받아들이는 서버/클라이언트
모델을 만들기가 매우 쉽다.
또한 Inet 소켓을 통한 외부통신에 비해서 2배 이상의 효율을 보여준다라는
장점을 가지고 있다.
많은 경우 약간 복잡한 내부프로세스간 통신을 해야된다고 했을때 UDS을 많이
사용한다. INET 계층에서의 통신이 TCP/IP 4계층을 모두 거치는것과는
다르게, UDS 은 어플리케이션 계층에서 TCP 계층까지만 메시지가 전달되고,
다시 곧바로 어플리케이션 계층으로 메시지가 올라가게 된다. TCP/IP 계층에 대한
자세한 내용은 TCP/IP 개요(2)를 참고 하기 바란다.
위에서 INET 소켓보다 2배이상의 효율을 가진다고 했는데,
4계층의 레이어를 모두 거쳐야하는 INET 소켓에 비해서 단지 2개의 레이어만
사용한다는 점도 그 이유중 하나로 작용한다.
쏘쓰 코드는 다중연결서버 만들기(1)의 zipcode_multi.c 와
셈플로 알아보는 소켓프로그래밍(1)의 zipcode_cli.c 를 사용하도록할것이다.
예제: zipcode_local.c
1.
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
int server_sockfd, client_sockfd;
int state, client_len;
pid_t pid;
FILE *fp;
struct sockaddr_un clientaddr, serveraddr;
char buf[255];
char line[255];
if (argc != 2)
{
printf("Usage : ./zipcode [file_name]\n");
printf("예 : ./zipcode /tmp/mysocket\n");
exit(0);
}
memset(line, '0', 255);
state = 0;
if (access(argv[1], F_OK) == 0)
{
unlink(argv[1]);
}
// 주소 파일을 읽어들인다.
client_len = sizeof(clientaddr);
if((fp = fopen("zipcode.txt", "r")) == NULL)
{
perror("file open error : ");
exit(0);
}
// internet 기반의 스트림 소켓을 만들도록 한다.
if ((server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
{
perror("socket error : ");
exit(0);
}
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sun_family = AF_UNIX;
strcpy(serveraddr.sun_path, argv[1]);
state = bind(server_sockfd , (struct sockaddr *)&serveraddr,
sizeof(serveraddr));
if (state == -1)
{
perror("bind error : ");
exit(0);
}
state = listen(server_sockfd, 5);
if (state == -1)
{
perror("listen error : ");
exit(0);
}
printf("accept : \n");
while(1)
{
client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr,
&client_len);
printf("test test\n");
pid = fork();
if (pid == 0)
{
if (client_sockfd == -1)
{
perror("Accept error : ");
exit(0);
}
while(1)
{
memset(buf, '0', 255);
if (read(client_sockfd, buf, 255) <= 0)
{
close(client_sockfd);
fclose(fp);
exit(0);
}
if (strncmp(buf, "quit",4) == 0)
{
write(client_sockfd, "bye bye\n", 8);
close(client_sockfd);
fclose(fp);
break;
}
while(fgets(line,255,fp) != NULL)
{
if (strstr(line, buf) != NULL)
write(client_sockfd, line, 255);
memset(line, '0', 255);
}
write(client_sockfd, "end", 255);
printf("send end\n");
rewind(fp);
}
}
}
close(client_sockfd);
}
}
다음은 클라이언트 프로그램이다.
예제: zipcode_cli_local.c
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
int client_len;
int client_sockfd;
FILE *fp_in;
char buf_in[255];
char buf_get[255];
struct sockaddr_un clientaddr;
if (argc != 2)
{
printf("Usage : ./zipcode_cl [file_name]\n");
printf("예 : ./zipcode_cl /tmp/mysocket\n");
exit(0);
}
client_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (client_sockfd == -1)
{
perror("error : ");
exit(0);
}
bzero(&clientaddr, sizeof(clientaddr));
clientaddr.sun_family = AF_UNIX;
strcpy(clientaddr.sun_path, argv[1]);
client_len = sizeof(clientaddr);
if (connect(client_sockfd, (struct sockaddr *)&clientaddr, client_len) < 0)
{
perror("Connect error: ");
exit(0);
}
while(1)
{
printf("지역이름 입력 : ");
fgets(buf_in, 255,stdin);
buf_in[strlen(buf_in) - 1] = '0';
write(client_sockfd, buf_in, 255);
if (strncmp(buf_in, "quit", 4) == 0)
{
close(client_sockfd);
exit(0);
}
while(1)
{
read(client_sockfd, buf_get, 255);
if (strncmp(buf_get, "end", 3) == 0)
break;
printf("%s", buf_get);
}
}
close(client_sockfd);
exit(0);
}
기존의 INET 버젼의 프로그램과 비교해 보면 고작 3줄 정도만 수정되었음을
알수 있을것이다. 단지 소켓 구조체가 sockaddr_un 으로 바뀌고,
AF_INET 대신 AF_UNIX 를 그리고 port 번호대신에 파일명을 사용했음을
알수 있다.
나머지의 모든 코드는 INET 코드와 완전히 같다. 그러므로
Unix Domain Socket 를 사용하면 Inet Domain Socket 와 코드 일관성을
유지할수 있으며, 동일한 기술을 사용해서 프로그래밍을 할수 있다.
또한 다른 대부분의 IPC 설비들이, 범용적으로 사용하기에는 부족한 여러가지
단점들을 가진반면(단방향 이거나, 읽기만 가능하다거나, 제어하기가 어려운)
UDS는 매우 범용적인 IPC 로써 사용가능하다라는 장점을 가지고 있다.
실제로 X 서버 같은경우에 외부에서의 접근시에는 INET 연결을 내부에서의
연결을 위해서는 UDS 를 사용한다. 이밖에도 mysql, pgsql, KDE, Gnome 과 같은
대부분의 서버프로그램이 내부통신을 위해서 UDS 를 사용한다.
2008년 6월 18일 수요일
2008년 6월 12일 목요일
2008년 6월 10일 화요일
Bubble Bobble Passwords
Bubble Bobble Passwords
Level Passwords
| Password | Effect |
|---|---|
| BBAAB | Level 01 |
| GGJBI | Level 96 |
| BIIIB | Level 04 |
| BIFFB | Level 05 |
| BFFFB | Level 06 |
| BFIIG | Level 07 |
| BJJJB | Level 08 |
| BJCCB | Level 09 |
| BCCCB | Level 10 |
| BCJJI | Level 11 |
| AFFFB | Level 20 |
| AJJJI | Level 26 |
| AGJJJ | Level 30 |
| IFIIG | Level 35 |
| IABBG | Level 39 |
| IEJJJ | Level 43 |
| FGJJJ | Level 58 |
| FCGGJ | Level 61 |
| FJEEJ | Level 63 |
| JIAAI | Level 77 |
| CCJJI | Level 81 |
| GEJJJ | Level 99 |
| BAAAB | Level 02 |
| AAAAB | Level 16 |
| BABBI | Level 03 |
| IIIIB | Level 32 |
| IGEEB | Level 41 |
| IEEEB | Level 42 |
| IJGGG | Level 44 |
| IJEEG | Level 45 |
| ICEEG | Level 46 |
| ICGGJ | Level 47 |
| FFFFB | Level 48 |
| FFIIG | Level 49 |
| FFIFG | Level 50 |
| FIIIG | Level 51 |
| FAAAJ | Level 52 |
| FABBG | Level 53 |
| FBBBG | Level 54 |
| FBAAG | Level 55 |
| FEEEB | Level 56 |
| FEJJJ | Level 57 |
| FGCCJ | Level 59 |
| FCEEG | Level 60 |
| CAJFI | Level 89 |
| GGJBI | Level 96 |
| EECJJ | Level B2 |
| GHCCB | Level C6 |
| HBGBD | Level E6 |
| HJFAB | Level F5 |
| IAAAJ | Level 38 |
| IBAAJ | Level 37 |
| IBBBJ | Level 36 |
| IFFFB | Level 34 |
| IIFFB | Level 33 |
| AGCCJ | Level 31 |
| AEJJJ | Level 29 |
| AEEEB | Level 28 |
| AJCCI | Level 27 |
| ACJJI | Level 25 |
| ACCCB | Level 24 |
| AIFFG | Level 23 |
| AIIIG | Level 22 |
| AFIIG | Level 21 |
| ABAAI | Level 19 |
| ABBBI | Level 18 |
| AABBI | Level 17 |
| BEJJJ | Level 15 |
| BEEEB | Level 14 |
| BGEEB | Level 13 |
| BGGGB | Level 12 |
| CJGEG | Level A0 |
| GJEGJ | Level A1 |
| GCEGJ | Level A2 |
| GCGEJ | Level A3 |
| GIBAI | Level A4 |
| GIABJ | Level A5 |
| GFABJ | Level A6 |
| GFBAJ | Level A7 |
| GBIFG | Level A8 |
| GBFIJ | Level A9 |
| GAFIJ | Level B0 |
| GAIFJ | Level B1 |
| CAFFI | Level 88 |
| CBIIB | Level 90 |
| CBFFB | Level 91 |
| CFAAI | Level 92 |
| CJBBJ | Level 93 |
| CIBBJ | Level 94 |
| CIAAJ | Level 95 |
| GGEEB | Level 97 |
| GEEEB | Level 98 |
| IGGGB | Level 40 |
| FJGGJ | Level 62 |
| JJJJB | Level 64 |
| JJCCB | Level 65 |
| JCCCB | Level 66 |
| JCJJI | Level 67 |
| JGGGB | Level 68 |
| JGEEB | Level 69 |
| JEEEB | Level 70 |
| JEJJJ | Level 71 |
| JBIII | Level 72 |
| JBFFI | Level 73 |
| JAFFI | Level 74 |
| JAIIB | Level 75 |
| JIBBI | Level 76 |
| CJJJI | Level 82 |
| CJCCI | Level 83 |
| CEEEB | Level 84 |
| CEJJJ | Level 85 |
| CGJJJ | Level 86 |
| CGCCJ | Level 87 |
| JFAAI | Level 78 |
| JFBBJ | Level 79 |
| CCCCB | Level 80 |
Other Passwords
| Password | Effect |
|---|---|
| EECFG | Skip to End |
| HEAGD | Stage Select (Super Bubble Bobble) |
| DDFFI | Stage Select (select 1/2p continue to make C9 appear, press A to raise level/B to lower) |
| BACCF | Start with 99 Lives |
Level Codes -- 99 and Ending
Enter at the screen where you select which game mode you want to play. There is a password field there.
| Password | Effect |
|---|---|
| GEJJJ | Level 99 (regular bubble bobble) |
| GEJIJ | Level 99 (super bubble bobble) |
| EGJJJ | Level B4 (last stage, regular bubble bobble) |
| EGJIJ | Level B4 (last stage, super bubble bobble) |
Super Bubble Bobble Round Passwords
Enter these passwords in the same place you normally enter round passwords on the mode select screen.
| Password | Effect |
|---|---|
| BBAJI | Round 01 |
| BAAJI | Round 02 |
| BABCI | Round 03 |
| BIIEB | Round 04 |
| BIAJJ | Round 05 |
| BFAJJ | Round 06 |
| BFBCJ | Round 07 |
| BJGFI | Round 08 |
| BJEIB | Round 09 |
| BCEIB | Round 10 |
| BCGFB | Round 11 |
| BGJAI | Round 12 |
| BGCBJ | Round 13 |
| BECBJ | Round 14 |
| BEJAJ | Round 15 |
| AAAJI | Round 16 |
| AABCI | Round 17 |
| ABBCI | Round 18 |
| ABFGG | Round 19 |
| AFAJJ | Round 20 |
| AFBCJ | Round 21 |
| AIBCJ | Round 22 |
| AIAJG | Round 23 |
| ACEIB | Round 24 |
| ACGFB | Round 25 |
| AJGFB | Round 26 |
| AJEIG | Round 27 |
| AECBJ | Round 28 |
| AEJAJ | Round 29 |
| AGJAJ | Round 30 |
| AGCBG | Round 31 |
| IIIEB | Round 32 |
| IIAJJ | Round 33 |
| IFAJJ | Round 34 |
| IFBCJ | Round 35 |
| IBIEG | Round 36 |
| IBFGJ | Round 37 |
| IAFGJ | Round 38 |
| IAIEJ | Round 39 |
| IGJAI | Round 40 |
| IGCBJ | Round 41 |
| IECBJ | Round 42 |
| IEJAJ | Round 43 |
| IJGFG | Round 44 |
| IJEIJ | Round 45 |
| ICEIJ | Round 46 |
| ICGFJ | Round 47 |
| FFAJJ | Round 48 |
| FFBCJ | Round 49 |
| FIBCJ | Round 50 |
| FIAJG | Round 51 |
| FAFGJ | Round 52 |
| FAIEJ | Round 53 |
| FBIEJ | Round 54 |
| FBFGI | Round 55 |
| FECBJ | Round 56 |
| FEJAJ | Round 57 |
| FGJAJ | Round 58 |
| FGCBG | Round 59 |
| FCEIJ | Round 60 |
| FCGFJ | Round 61 |
| FJGFJ | Round 62 |
| FJAJJ | Round 63 |
| JJGFI | Round 64 |
| JJEIB | Round 65 |
| JCEIB | Round 66 |
| JCGFB | Round 67 |
| JGJAI | Round 68 |
| JGCBJ | Round 69 |
| JECBJ | Round 70 |
| JEJAJ | Round 71 |
| JBIEI | Round 72 |
| JBFGB | Round 73 |
| JAFGB | Round 74 |
| JAIEB | Round 75 |
| JIBCI | Round 76 |
| JIEII | Round 77 |
| JFEII | Round 78 |
| JFGFI | Round 79 |
| CCEIB | Round 80 |
| CCGFB | Round 81 |
| CJGFB | Round 82 |
| CJEIG | Round 83 |
| CECBJ | Round 84 |
| CEJAJ | Round 85 |
| CGJAJ | Round 86 |
| CGCBG | Round 87 |
| CAFGB | Round 88 |
| CAIEB | Round 89 |
| CBIEB | Round 90 |
| CBCBB | Round 91 |
| CFEII | Round 92 |
| CFGFI | Round 93 |
| CIGFI | Round 94 |
| CIEIB | Round 95 |
| GGJAI | Round 96 |
| GGCBJ | Round 97 |
| GECBJ | Round 98 |
| GEJAJ | Round 99 |
| GJGBG | Round A0 |
| GJEAG | Round A1 |
| GCEAG | Round A2 |
| GCBGG | Round A3 |
| GIGBB | Round A4 |
| GIEAB | Round A5 |
| GFEAB | Round A6 |
| GFGBI | Round A7 |
| GBJIB | Round A8 |
| GBCFB | Round A9 |
| GACFB | Round B0 |
| GAJIG | Round B1 |
| EECFG | Round B2 |
Bubble Bobble Unlockables
Unlockables
| Unlockable | How to Unlock |
|---|---|
| Sound Test | Beat Super Bubble Bobble Mode and get happy ending |
Bubble Bobble Secrets
Add in the 2nd Player
During gameplay, pause the game and press Select to activate the 2nd Player.
Steal Lives
If you die in a two-player game, hit Start to pause the game, then hit Select to steal a life from your partner.
Happy Ending
Take the Crystal (found in Room 99) to Room A0. At the final boss (Room B3), fire at him until he is encased in a bubble. Now, instead of popping it right away, first hit Start to summon Player 2 (you must have at least one life left). Now pop the bubble for the ''good'' ending.
Secret diamond room
To gain access to a secret room worth 400,000 points, survive 20 rounds with your first dinosaur.
2008년 6월 2일 월요일
2008년 6월 1일 일요일
피드 구독하기:
글 (Atom)


