ICE3013 시스템 프로그래밍 기말고사 대비 내용 정리 🤓
: 각 주차에 배운 내용 간단히 요약
9주차 + 10주차 : exec, shell
11주차 : network
12주차 : network2
13주차 : select
14주차 : signal
ex1.c
#include <stdio.h>
void main() {
printf("I am ex1\n");
}
ex2.c
#include <stdio.h>
void main() {
execve("./ex1", 0, 0);
printf("I am ex2\n");
}
printf("I am ex2\n");
는 실행되지 않음#include <stdio.h>
void main() {
char *k[10];
k[0] = "/bin/ls";
k[1] = 0;
execve(k[0], k, 0);
}
#include <stdio.h>
void main() {
char *k[10];
k[0] = "/bin/cat";
k[1] = "f1";
k[2] = 0;
execve(k[0], k, 0);
}
#include <stdio.h>
void main() {
char *k[10];
k[0] = "/bin/ls";
k[1] = "-l";
k[2] = 0;
execve(k[0], k, 0);
}
#include <stdio.h>
void main() {
char *k[10];
k[0] = "/bin/cp";
k[1] = "f1";
k[2] = "f2"
k[3] = 0;
execve(k[0], k, 0);
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
void main() {
if(fork() == 0) { // 자식 프로세스
char *k[10];
k[0] = "/bin/ls";
k[1] = "-l";
k[2] = 0;
execve(k[0], k, 0);
}
else { // 부모 프로세스
wait(0);
printf("job done\n");
}
#include <stdio.h>
#include <string.h>
void main() {
char buf[256];
char *token;
char *k[10];
// 입력값을 받아 buf 배열에 저장
fgets(buf, 255, stdin);
buf[strlen(buf)-1] = 0;
// 공백을 기준으로 문자열 split 후 k 배열에 저장
token = strtok(buf, " ");
int i = 0;
for(;;) {
k[i] = (char*)malloc(strlen(token+1));
strcpy(k[i], token);
token = strtok(NULL, " ");
i++;
if(token==NULL) break;
}
k[i] = 0;
execve(k[0], k, 0); // 명령어 실행
}
/bin/cat
, /bin/ls
등 자신이 원하는 명령어를 사용 가능0
!!!!#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
void main() {
int j;
for(j=0; j<5; j++) {
if (fork()==0) { // 자식 프로세스
char buf[256];
char *token;
char *k[10];
// 입력값을 받아 buf 배열에 저장
fgets(buf, 255, stdin);
buf[strlen(buf)-1] = 0;
// 공백을 기준으로 문자열 split 후 k 배열에 저장
token = strtok(buf, " ");
int i = 0;
for(;;) {
k[i] = (char*)malloc(strlen(token+1));
strcpy(k[i], token);
token = strtok(NULL, " ");
i++;
if(token==NULL) break;
}
k[i] = 0;
execve(k[0], k, 0); // 명령어 실행
}
else {
wait(0);
}
}
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
void main() {
int j;
for(j=0; j<5; j++) {
if (fork()==0) { // 자식 프로세스
// 추가된 부분
// ---------------------------
char *cwd;
char wd[BUFSIZ];
cwd = getcwd(NULL, BUFSIZ);
printf("[%s]$ ", cwd);
// ---------------------------
char buf[256];
char *token;
char *k[10];
// 입력값을 받아 buf 배열에 저장
fgets(buf, 255, stdin);
buf[strlen(buf)-1] = 0;
// 공백을 기준으로 문자열 split 후 k 배열에 저장
token = strtok(buf, " ");
int i = 0;
for(;;) {
k[i] = (char*)malloc(strlen(token+1));
strcpy(k[i], token);
token = strtok(NULL, " ");
i++;
if(token==NULL) break;
}
k[i] = 0;
execve(k[0], k, 0); // 명령어 실행
}
else {
wait(0);
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
void main() {
int i, x;
for(;;) {
printf("Child process to execute\n");
char buf[100];
printf("$ ");
scanf("%s", buf);
if(strcmp(buf, "exit")==0) break;
char* argv[] = { buf, 0 };
x = fork();
if(x==0) {
if(execve(buf, argv, 0) < 0) perror("Fail to execute\n");
execve(buf, argv, 0);
}
else wait(0);
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
void main() {
int i, x;
for(;;) {
char buf[100];
char *token;
printf("$ ");
fgets(buf, 255, stdin);
buf[strlen(buf)-1] = 0;
if(strcmp(buf, "exit")==0) break;
x = fork();
if(x==0) {
printf("Child process to execute\n");
char* argv[10];
token = strtok(buf, " ");
int i=0;
for(;;) {
argv[i] = (char*)malloc(strlen(token+1));
strcpy(argv[i], token);
token = strtok(NULL, " ");
i++;
if(token==NULL) break;
}
argv[i] = 0
if(execve(buf, argv, 0) < 0) {
perror("Fail to execute\n");
exit(EXIT_FAILURE);
}
execve(buf, argv, 0);
}
else wait(0);
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
void main() {
int i, x;
for(;;) {
char buf[100];
printf("$ ");
fgets(buf, 255, stdin);
buf[strlen(buf)-1] = '\0';
if(strcmp(buf, "exit")==0) break;
char* argv[100];
int argc = 0;
argv[argc] = strtok(buf, " ");
while (argv[argc]!=NULL) {
argc++;
argv[argc] = strtok(NULL, " ");
}
if(fork()==0) {
printf("Child process to execute\n");
if(execve(buf, argv, 0) < 0) {
perror("Fail to execute\n");
exit(EXIT_FAILURE);
}
}
else {
if(argv[argc-1][0] != '&') wait(0);
else sleep(1);
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
void main() {
for(;;) {
char buf[100];
printf("$ ");
fgets(buf, 255, stdin);
buf[strlen(buf)-1] = '\0';
if(strcmp(buf, "exit")==0) break;
char* argv[100];
int argc = 0;
argv[argc] = strtok(buf, " ");
while (argv[argc]!=NULL) {
argc++;
argv[argc] = strtok(NULL, " ");
}
if(fork()==0) {
printf("Child process to execute\n");
char pathname[100];
sprintf(pathname, "%s%s", "/bin", argv[0]);
if(execve(pathname, argv, 0) < 0) {
perror("Fail to execute\n");
exit(EXIT_FAILURE);
}
}
else {
if(argv[argc-1][0] != '&') wait(0);
else sleep(1);
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
void main() {
char* s;
s = getenv("PATH");
char* arr[100];
int i=0;
arr[i] = strtok(s, ":");
while(arr[i]!=NULL) {
i++;
arr[i] = strtok(NULL, ":");
}
int j;
for(j=0; j<i; j++) {
printf("%s\n", arr[j]);
}
}
:
를 기준으로 문자열을 잘라 출력하여 더 보기 편하도록 하였다.#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
void main() {
for(;;) {
char buf[100];
printf("$ ");
fgets(buf, 255, stdin);
buf[strlen(buf)-1] = '\0';
if(strcmp(buf, "exit")==0) break;
char* argv[100];
int argc = 0;
argv[argc] = strtok(buf, " ");
while (argv[argc]!=NULL) {
argc++;
argv[argc] = strtok(NULL, " ");
}
if(fork()==0) {
printf("Child process to execute\n");
char *s = strtok(getenv("PATH"), ":");
while (s!=NULL) {
char pathname[100];
sprintf(pathname, "%s%s", s, argv[0]);
if(execve(pathname, argv, 0) < 0) {
s = strtok(NULL, ":");
}
else exit(EXIT_SUCCESS);
}
perror("Fail to execute\n");
exit(EXIT_FAILURE);
}
else {
if(argv[argc-1][0] != '&') wait(0);
else sleep(1);
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
void main() {
for(;;) {
char buf[100];
printf("$ ");
fgets(buf, 255, stdin);
buf[strlen(buf)-1] = '\0';
if(strcmp(buf, "exit")==0) break;
char* argv[100];
int argc = 0;
argv[argc] = strtok(buf, " ");
while (argv[argc]!=NULL) {
argc++;
argv[argc] = strtok(NULL, " ");
}
if(fork()==0) {
printf("Child process to execute\n");
if (argv[argc-2][0] == '>') {
int fd = open(argv[argc-1], O_WRONLY|O_CREAT|O_TRUNC, 00777);
dup2(fd, STDOUT_FILENO);
close(fd);
}
char *s = strtok(getenv("PATH"), ":");
while (s!=NULL) {
char pathname[100];
sprintf(pathname, "%s%s", s, argv[0]);
if(execve(pathname, argv, 0) < 0) {
s = strtok(NULL, ":");
}
else exit(EXIT_SUCCESS);
}
perror("Fail to execute\n");
exit(EXIT_FAILURE);
}
else {
if(argv[argc-1][0] != '&') wait(0);
else sleep(1);
}
}
}
>
을 이용한 redirection 기능을 추가>
일 때 dup2() 함수를 이용하여 기존 file descriptor로 가는 호출을 새로운 file descriptor로 가도록 함serv.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#define SERV_TCP_PORT 13579
#define SERV_ADDR "165.246.38.152"
int main(void) {
int s1, s2, x, y;
struct sockaddr_in serv_addr, cli_addr;
char buf[50];
socklen_t xx;
printf("Hi, I am the server\n");
bzero((char*) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = PF_INET;
serv_addr.sin_addr.s_addr = inet_addr(SERV_ADDR);
serv_addr.sin_port = htons(SERV_TCP_PORT);
//open a tcp socket
if ((s1 = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("socket creation error\n");
exit(1);
}
printf("socket opened successfully. socket num is %d\n", s1);
// bind ip
x = bind(s1, (struct sockaddr*) &serv_addr, sizeof(serv_addr));
if (x < 0) {
printf("binding failed\n");
exit(1);
}
printf("binding passed\n");
listen(s1, 5);
xx = sizeof(cli_addr);
s2 = accept(s1, (struct sockaddr*) &cli_addr, &xx);
printf("we passed accept. new socket num is %d\n", s2);
// >>>>>>>>>>>>>>>>> 여기서부터 보면 됨 !! <<<<<<<<<<<<<<<<<<<<
// read msg from client
printf("now reading from client\n");
y = read(s2, buf, 50);
buf[y] = 0;
printf("we got %s from cli\n", buf);
// send msg to the client
printf("enter a string to send to client\n");
scanf("%s", buf);
write(s2, buf, strlen(buf));
close(s2); // disconnect the connection
close(s1); // close the original socket
return 0;
}
cli.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#define SERV_TCP_PORT 13579
#define SERV_ADDR "165.246.38.152"
int main(void) {
int x, y;
struct sockaddr_in serv_addr;
char buf[50];
printf("Hi, I am the client\n");
bzero((char*) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = PF_INET;
serv_addr.sin_addr.s_addr = inet_addr(SERV_ADDR);
serv_addr.sin_port = htons(SERV_TCP_PORT);
//open a tcp socket
if ((x = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("socket creation error\n");
exit(1);
}
printf("socket opened successfully. socket num is %d\n", x);
// >>>>>>>>>>>>>>>>> 여기서부터 보면 됨 !! <<<<<<<<<<<<<<<<<<<<
//connect to the server
if (connect(x, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0) {
printf("can't connect to the server\n");
exit(1);
}
// send msg to the server
printf("now i am connected to the server. enter a string to send\n");
scanf("%s", buf);
write(x, buf, strlen(buf));
// read from server
printf("now reading from server\n");
y = read(x, buf, 50);
buf[y] = 0;
printf("from server: %s\n", buf);
close(x); // disconect the communication
return 0;
}
serv.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define LISTEN_BACKLOG 5
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
int main(void) {
printf("Hi, I am the server.\n");
struct sockaddr_in serv_addr, cli_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Server socket(sfd=%d) is created.\n", sfd);
if (bind(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to bind");
exit(EXIT_FAILURE);
}
if (listen(sfd, LISTEN_BACKLOG) == -1) {
perror("Fail to listen");
exit(EXIT_FAILURE);
}
socklen_t cli_addr_len = sizeof(cli_addr);
int cfd = accept(sfd, (struct sockaddr*) &cli_addr, &cli_addr_len);
if (cfd == -1) {
perror("Fail to accept");
exit(EXIT_FAILURE);
}
printf("Client socket(cfd=%d) is accepted.\n", cfd);
char buf[BUFFER_SIZE];
int chunk = read(cfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("receive: %s\n", buf);
// scanf() 대신 fgets() 사용
fgets(buf, BUFFER_SIZE - 1, stdin);
buf[strlen(buf) - 1] = '\0';
write(cfd, buf, strlen(buf));
close(cfd);
close(sfd);
return 0;
}
cli.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
int main(void) {
printf("Hi, I am the client.\n");
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Socket(sfd=%d) is created.\n", sfd);
if (connect(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to connect");
exit(EXIT_FAILURE);
}
// scanf() 대신 fgets() 사용
char buf[BUFFER_SIZE];
fgets(buf, BUFFER_SIZE - 1, stdin);
buf[strlen(buf) - 1] = '\0';
write(sfd, buf, strlen(buf));
int chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("receive: %s\n", buf);
close(sfd);
return 0;
}
serv.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define LISTEN_BACKLOG 5
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
int main(void) {
printf("Hi, I am the server.\n");
struct sockaddr_in serv_addr, cli_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Server socket(sfd=%d) is created.\n", sfd);
if (bind(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to bind");
exit(EXIT_FAILURE);
}
if (listen(sfd, LISTEN_BACKLOG) == -1) {
perror("Fail to listen");
exit(EXIT_FAILURE);
}
socklen_t cli_addr_len = sizeof(cli_addr);
int cfd = accept(sfd, (struct sockaddr*) &cli_addr, &cli_addr_len);
if (cfd == -1) {
perror("Fail to accept");
exit(EXIT_FAILURE);
}
printf("Client socket(cfd=%d) is accepted.\n", cfd);
char buf[BUFFER_SIZE];
while (1) {
int chunk = read(cfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
if (strcmp(buf, "bye") == 0) {
break;
}
printf("receive: %s\n", buf);
fgets(buf, BUFFER_SIZE - 1, stdin);
buf[strlen(buf) - 1] = '\0';
write(cfd, buf, strlen(buf));
if (strcmp(buf, "bye") == 0) {
break;
}
}
close(cfd);
close(sfd);
return 0;
}
cli.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
int main(void) {
printf("Hi, I am the client.\n");
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Socket(sfd=%d) is created.\n", sfd);
if (connect(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to connect");
exit(EXIT_FAILURE);
}
char buf[BUFFER_SIZE];
while (1) {
fgets(buf, BUFFER_SIZE - 1, stdin);
buf[strlen(buf) - 1] = '\0';
write(sfd, buf, strlen(buf));
if (strcmp(buf, "bye") == 0) {
break;
}
int chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
if (strcmp(buf, "bye") == 0) {
break;
}
printf("receive: %s\n", buf);
}
close(sfd);
return 0;
}
while(1)
으로 감싸고, strcmp()를 이용하여 "bye"가 입력되면 무한 루프에서 빠져 나오도록 코드를 수정했다.cli.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define SERV_ADDR "165.246.13.108" // www.inha.ac.kr
#define SERV_PORT 80
int main(void) {
printf("Hi, I am the client.\n");
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Socket(sfd=%d) is created.\n", sfd);
if (connect(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to connect");
exit(EXIT_FAILURE);
}
char* request = "GET / HTTP/1.1\r\nHOST: www.inha.ac.kr\r\n\r\n";
write(sfd, request, strlen(request));
char buf[BUFFER_SIZE];
int chunk;
while ((chunk = recv(sfd, buf, BUFFER_SIZE - 1, 0)) > 0) {
buf[chunk] = '\0';
printf("%s", buf);
}
close(sfd);
return 0;
}
serv.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define LISTEN_BACKLOG 5
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
int main(void) {
printf("Hi, I am the server.\n");
struct sockaddr_in serv_addr, cli_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Server socket(sfd=%d) is created.\n", sfd);
if (bind(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to bind");
exit(EXIT_FAILURE);
}
if (listen(sfd, LISTEN_BACKLOG) == -1) {
perror("Fail to listen");
exit(EXIT_FAILURE);
}
socklen_t cli_addr_len = sizeof(cli_addr);
int cfd = accept(sfd, (struct sockaddr*) &cli_addr, &cli_addr_len);
if (cfd == -1) {
perror("Fail to accept");
exit(EXIT_FAILURE);
}
printf("Client socket(cfd=%d) is accepted.\n", cfd);
char buf[BUFFER_SIZE];
pid_t child_pid = fork();
if (child_pid == 0) { // child
// send message
while (1) {
fgets(buf, BUFFER_SIZE - 1, stdin);
buf[strlen(buf) - 1] = '\0';
write(cfd, buf, strlen(buf));
if (strcmp(buf, "bye") == 0) {
kill(getppid(), SIGKILL);
break;
}
}
} else { // parent
// receive message
while (1) {
int chunk = read(cfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
if (strcmp(buf, "bye") == 0) {
kill(child_pid, SIGKILL);
break;
}
printf("receive: %s\n", buf);
}
}
close(cfd);
close(sfd);
return 0;
}
cli.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
int main(void) {
printf("Hi, I am the client.\n");
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Socket(sfd=%d) is created.\n", sfd);
if (connect(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to connect");
exit(EXIT_FAILURE);
}
char buf[BUFFER_SIZE];
pid_t child_pid = fork();
// send message
if (child_pid == 0) { // child
while (1) {
fgets(buf, BUFFER_SIZE - 1, stdin);
buf[strlen(buf) - 1] = '\0';
write(sfd, buf, strlen(buf));
if (strcmp(buf, "bye") == 0) {
kill(getppid(), SIGKILL);
break;
}
}
} else { // parent
// receive message
while (1) {
int chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
if (strcmp(buf, "bye") == 0) {
kill(child_pid, SIGKILL);
break;
}
printf("receive: %s\n", buf);
}
}
close(sfd);
return 0;
}
serv.c
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define LISTEN_BACKLOG 5
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
int main(void) {
printf("Hi, I am the FTP server.\n");
struct sockaddr_in serv_addr, cli_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Server socket(sfd=%d) is created.\n", sfd);
if (bind(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to bind");
exit(EXIT_FAILURE);
}
if (listen(sfd, LISTEN_BACKLOG) == -1) {
perror("Fail to listen");
exit(EXIT_FAILURE);
}
socklen_t cli_addr_len = sizeof(cli_addr);
int cfd = accept(sfd, (struct sockaddr*) &cli_addr, &cli_addr_len);
if (cfd == -1) {
perror("Fail to accept");
exit(EXIT_FAILURE);
}
printf("Client socket(cfd=%d) is accepted.\n", cfd);
char buf[BUFFER_SIZE];
int chunk = read(cfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("client => server: %s\n", buf);
if (strcmp(buf, "hello") == 0) {
char* init_response = "What file do you want?";
write(cfd, init_response, strlen(init_response));
printf("server => client: %s\n", init_response);
buf[0] = -1;
write(cfd, buf, 1);
while (1) {
// read file name from client
chunk = read(cfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("client => server: %s\n", buf);
if (strcmp(buf, "bye") == 0) {
break;
}
int fd = open(buf, O_RDONLY);
if (fd == -1) {
char* response = "Fail to open the file.";
write(cfd, response, strlen(response));
printf("server => client: %s\n", response);
buf[0] = -1;
write(cfd, buf, 1);
continue;
}
printf("server => client: ");
fflush(stdout);
while ((chunk = read(fd, buf, BUFFER_SIZE))) {
write(cfd, buf, chunk);
write(STDOUT_FILENO, buf, chunk);
}
buf[0] = -1;
write(cfd, buf, 1);
printf("\n");
close(fd);
}
}
close(cfd);
close(sfd);
return 0;
}
cli.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
int main(void) {
printf("Hi, I am the FTP client.\n");
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Socket(sfd=%d) is created.\n", sfd);
if (connect(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to connect");
exit(EXIT_FAILURE);
}
char* init_request = "hello";
write(sfd, init_request, strlen(init_request));
printf("client => server: hello\n");
while (1) {
char buf[BUFFER_SIZE];
int chunk;
printf("server => client: ");
fflush(stdout);
while (1) {
chunk = read(sfd, buf, BUFFER_SIZE);
if (buf[chunk - 1] == -1) {
write(STDOUT_FILENO, buf, chunk - 1);
break;
} else {
write(STDOUT_FILENO, buf, chunk);
}
}
printf("\n");
printf("client => server: ");
fgets(buf, BUFFER_SIZE - 1, stdin);
buf[strlen(buf) - 1] = '\0';
write(sfd, buf, strlen(buf));
if (strcmp(buf, "bye") == 0) {
break;
}
}
close(sfd);
return 0;
}
cli.c는 그대로
serv.c
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define LISTEN_BACKLOG 5
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
int main(void) {
printf("Hi, I am the FTP server.\n");
struct sockaddr_in serv_addr, cli_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Server socket(sfd=%d) is created.\n", sfd);
if (bind(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to bind");
exit(EXIT_FAILURE);
}
if (listen(sfd, LISTEN_BACKLOG) == -1) {
perror("Fail to listen");
exit(EXIT_FAILURE);
}
socklen_t cli_addr_len = sizeof(cli_addr);
while (1) {
int cfd = accept(sfd, (struct sockaddr*) &cli_addr, &cli_addr_len);
if (cfd == -1) {
perror("Fail to accept");
exit(EXIT_FAILURE);
}
printf("Client socket(cfd=%d) is accepted.\n", cfd);
if (fork() == 0) {
char buf[BUFFER_SIZE];
int chunk = read(cfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("client => server: %s\n", buf);
if (strcmp(buf, "hello") == 0) {
char* init_response = "What file do you want?";
write(cfd, init_response, strlen(init_response));
printf("server => client: %s\n", init_response);
buf[0] = -1;
write(cfd, buf, 1);
while (1) {
chunk = read(cfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("client => server: %s\n", buf);
if (strcmp(buf, "bye") == 0) {
break;
}
int fd = open(buf, O_RDONLY);
if (fd == -1) {
char* response = "Fail to open the file.";
write(cfd, response, strlen(response));
printf("server => client: %s\n", response);
buf[0] = -1;
write(cfd, buf, 1);
continue;
}
printf("server => client: ");
fflush(stdout);
while ((chunk = read(fd, buf, BUFFER_SIZE))) {
write(cfd, buf, chunk);
write(STDOUT_FILENO, buf, chunk);
}
buf[0] = -1;
write(cfd, buf, 1);
printf("\n");
close(fd);
}
}
close(cfd);
close(sfd);
exit(EXIT_SUCCESS);
}
close(cfd);
}
close(sfd);
return 0;
}
lab server - PC 간 Simple FTP 구현 & lab server → PC로 파일 다운로드은 생략 !
serv.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define LISTEN_BACKLOG 5
#define MAX_FD_COUNT 50
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
void handle_protocol(int fd, fd_set* set, int recv_count);
int main(void) {
printf("Hi, I am the server.\n");
struct sockaddr_in serv_addr, cli_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Server socket(sfd=%d) is created.\n", sfd);
if (bind(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to bind");
exit(EXIT_FAILURE);
}
if (listen(sfd, LISTEN_BACKLOG) == -1) {
perror("Fail to listen");
exit(EXIT_FAILURE);
}
socklen_t cli_addr_len = sizeof(cli_addr);
fd_set read_fds, temp_fds;
FD_ZERO(&read_fds);
FD_SET(sfd, &read_fds);
int recv_counts[MAX_FD_COUNT] = { 0 };
while (1) {
temp_fds = read_fds;
select(MAX_FD_COUNT, &temp_fds, NULL, NULL, NULL);
for (int fd = 0; fd < MAX_FD_COUNT; fd += 1) {
if (FD_ISSET(fd, &temp_fds)) {
if (fd == sfd) {
int cfd = accept(sfd, (struct sockaddr*) &cli_addr, &cli_addr_len);
if (cfd == -1) {
perror("Fail to accept");
exit(EXIT_FAILURE);
}
printf("Client socket(cfd=%d) is accepted.\n", cfd);
FD_SET(cfd, &read_fds);
} else {
recv_counts[fd] += 1;
handle_protocol(fd, &read_fds, recv_counts[fd]);
}
}
}
}
return 0;
}
void handle_protocol(int fd, fd_set* set, int recv_count) {
char buf[BUFFER_SIZE];
int chunk = read(fd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("client(cfd=%d) => server: %s\n", fd, buf);
if (strcmp(buf, "ping") == 0 && recv_count == 1) {
write(fd, "pong", 4);
printf("server => client(cfd=%d): pong\n", fd);
} else if (strcmp(buf, "pang") == 0 && recv_count == 2) {
write(fd, "pung", 4);
printf("server => client(cfd=%d): pung\n", fd);
} else if (strcmp(buf, "ping") == 0 && recv_count == 3) {
write(fd, "Process completed.", 18);
printf("server => client(cfd=%d): Process completed.\n", fd);
printf("Client socket(cfd=%d) is closed.\n", fd);
close(fd);
FD_CLR(fd, set);
} else {
write(fd, "Invalid input to protocol.", 26);
fprintf(stderr, "Invalid input to protocol.\n");
printf("Client socket(cfd=%d) is closed.\n", fd);
close(fd);
FD_CLR(fd, set);
}
}
cli.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
int main(void) {
printf("Hi, I am the client.\n");
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Socket(sfd=%d) is created.\n", sfd);
if (connect(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to connect");
exit(EXIT_FAILURE);
}
char buf[BUFFER_SIZE];
printf("client => server: (Enter ping) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
int chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "pong") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
printf("client => server: (Enter pang) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "pung") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
printf("client => server: (Enter ping) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
close(sfd);
return 0;
}
serv.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define LISTEN_BACKLOG 5
#define MAX_FD_COUNT 50
#define MAX_NAME_LENGTH 20
#define MAX_AGE_LENGTH 5
#define MAX_CLIENT_COUNT 50
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
#define STATE_UNDEFINED 0
#define STATE_INIT 1
#define STATE_PROTOCOL 2
#define STATE_ASK_NAME 3
#define STATE_ASK_AGE 4
#define STATE_CHAT 5
typedef struct client {
char name[MAX_NAME_LENGTH];
char age[MAX_AGE_LENGTH];
} CLIENT;
void handle_protocol(int fd, fd_set* set, int* states, CLIENT* clients);
int main(void) {
printf("Hi, I am the server.\n");
struct sockaddr_in serv_addr, cli_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Server socket(sfd=%d) is created.\n", sfd);
if (bind(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to bind");
exit(EXIT_FAILURE);
}
if (listen(sfd, LISTEN_BACKLOG) == -1) {
perror("Fail to listen");
exit(EXIT_FAILURE);
}
socklen_t cli_addr_len = sizeof(cli_addr);
fd_set read_fds, temp_fds;
FD_ZERO(&read_fds);
FD_SET(sfd, &read_fds);
int states[MAX_FD_COUNT] = { STATE_UNDEFINED };
CLIENT clients[MAX_CLIENT_COUNT];
while (1) {
temp_fds = read_fds;
select(MAX_FD_COUNT, &temp_fds, NULL, NULL, NULL);
for (int fd = 0; fd < MAX_FD_COUNT; fd += 1) {
if (FD_ISSET(fd, &temp_fds)) {
if (fd == sfd) {
int cfd = accept(sfd, (struct sockaddr*) &cli_addr, &cli_addr_len);
if (cfd == -1) {
perror("Fail to accept");
exit(EXIT_FAILURE);
}
states[cfd] = STATE_INIT;
printf("Client socket(cfd=%d) is accepted.\n", cfd);
FD_SET(cfd, &read_fds);
} else {
handle_protocol(fd, &read_fds, states, clients);
}
}
}
}
return 0;
}
void handle_protocol(int fd, fd_set* set, int* states, CLIENT* clients) {
char buf[BUFFER_SIZE];
int chunk = read(fd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("client(cfd=%d) => server: %s\n", fd, buf);
int state = states[fd];
if (state == STATE_INIT && strcmp(buf, "ping") == 0) {
write(fd, "pong", 4);
printf("server => client(cfd=%d): pong\n", fd);
states[fd] += 1;
} else if (state == STATE_PROTOCOL && strcmp(buf, "pang") == 0) {
write(fd, "pung. Enter your name.", 22);
printf("server => client(cfd=%d): pung. Enter your name.\n", fd);
states[fd] += 1;
} else if (state == STATE_ASK_NAME && strlen(buf) > 0) {
strcpy(clients[fd].name, buf);
write(fd, "Enter your age.", 15);
printf("server => client(cfd=%d): Enter your age.\n", fd);
states[fd] += 1;
} else if (state == STATE_ASK_AGE && strlen(buf) > 0) {
strcpy(clients[fd].age, buf);
write(fd, "Process completed. Start chatting.", 34);
printf("server => client(cfd=%d): Process completed. Start chatting.\n", fd);
states[fd] += 1;
} else if (state == STATE_CHAT && strlen(buf) > 0) {
for (int other_fd = 0; other_fd < MAX_FD_COUNT; other_fd += 1) {
if (fd != other_fd && states[other_fd] == STATE_CHAT) {
write(other_fd, buf, strlen(buf));
printf("server => client(cfd=%d): %s\n", other_fd, buf);
}
}
} else {
write(fd, "Invalid input to protocol.", 26);
fprintf(stderr, "Invalid input to protocol.\n");
printf("Client socket(cfd=%d) is closed.\n", fd);
close(fd);
FD_CLR(fd, set);
}
}
cli.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
int main(void) {
printf("Hi, I am the client.\n");
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Socket(sfd=%d) is created.\n", sfd);
if (connect(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to connect");
exit(EXIT_FAILURE);
}
char buf[BUFFER_SIZE];
printf("client => server: (Enter ping) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
int chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "pong") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
printf("client => server: (Enter pang) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "pung. Enter your name.") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
printf("client => server: (Enter your name) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "Enter your age.") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
printf("client => server: (Enter your age) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "Process completed. Start chatting.") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
if (fork() == 0) {
while (1) {
chunk = read(sfd, buf, BUFFER_SIZE - 1);
if (chunk > 0) {
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
}
}
} else {
while (1) {
printf("client => server: (Chat) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
}
}
close(sfd);
return 0;
}
serv.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define LISTEN_BACKLOG 5
#define MAX_FD_COUNT 50
#define MAX_NAME_LENGTH 20
#define MAX_AGE_LENGTH 5
#define MAX_CLIENT_COUNT 50
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
#define STATE_UNDEFINED 0
#define STATE_INIT 1
#define STATE_PROTOCOL 2
#define STATE_ASK_NAME 3
#define STATE_ASK_AGE 4
#define STATE_ASK_PARTNER 5
#define STATE_CHAT 6
typedef struct client {
char name[MAX_NAME_LENGTH];
char age[MAX_AGE_LENGTH];
int partner;
} CLIENT;
void handle_protocol(int fd, fd_set* set, int* states, CLIENT* clients);
int main(void) {
printf("Hi, I am the server.\n");
struct sockaddr_in serv_addr, cli_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Server socket(sfd=%d) is created.\n", sfd);
if (bind(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to bind");
exit(EXIT_FAILURE);
}
if (listen(sfd, LISTEN_BACKLOG) == -1) {
perror("Fail to listen");
exit(EXIT_FAILURE);
}
socklen_t cli_addr_len = sizeof(cli_addr);
fd_set read_fds, temp_fds;
FD_ZERO(&read_fds);
FD_SET(sfd, &read_fds);
int states[MAX_FD_COUNT] = { STATE_UNDEFINED };
CLIENT clients[MAX_CLIENT_COUNT];
while (1) {
temp_fds = read_fds;
select(MAX_FD_COUNT, &temp_fds, NULL, NULL, NULL);
for (int fd = 0; fd < MAX_FD_COUNT; fd += 1) {
if (FD_ISSET(fd, &temp_fds)) {
if (fd == sfd) {
int cfd = accept(sfd, (struct sockaddr*) &cli_addr, &cli_addr_len);
if (cfd == -1) {
perror("Fail to accept");
exit(EXIT_FAILURE);
}
states[cfd] = STATE_INIT;
printf("Client socket(cfd=%d) is accepted.\n", cfd);
FD_SET(cfd, &read_fds);
} else {
handle_protocol(fd, &read_fds, states, clients);
}
}
}
}
return 0;
}
void handle_protocol(int fd, fd_set* set, int* states, CLIENT* clients) {
char buf[BUFFER_SIZE];
int chunk = read(fd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("client(cfd=%d) => server: %s\n", fd, buf);
int state = states[fd];
if (state == STATE_INIT && strcmp(buf, "ping") == 0) {
write(fd, "pong", 4);
printf("server => client(cfd=%d): pong\n", fd);
states[fd] += 1;
} else if (state == STATE_PROTOCOL && strcmp(buf, "pang") == 0) {
write(fd, "pung. Enter your name.", 22);
printf("server => client(cfd=%d): pung. Enter your name.\n", fd);
states[fd] += 1;
} else if (state == STATE_ASK_NAME && strlen(buf) > 0) {
strcpy(clients[fd].name, buf);
write(fd, "Enter your age.", 15);
printf("server => client(cfd=%d): Enter your age.\n", fd);
states[fd] += 1;
} else if (state == STATE_ASK_AGE && strlen(buf) > 0) {
strcpy(clients[fd].age, buf);
write(fd, "Enter your partner.", 19);
printf("server => client(cfd=%d): Enter your partner.\n", fd);
states[fd] += 1;
} else if (state == STATE_ASK_PARTNER && strlen(buf) > 0) {
for (int other_fd = 0; other_fd < MAX_FD_COUNT; other_fd += 1) {
if (fd != other_fd && states[other_fd] > STATE_ASK_NAME && strcmp(buf, clients[other_fd].name) == 0) {
clients[fd].partner = other_fd;
write(fd, "Process completed. Start chatting.", 34);
printf("server => client(cfd=%d): Process completed. Start chatting.\n", fd);
states[fd] += 1;
break;
}
}
} else if (state == STATE_CHAT && strlen(buf) > 0) {
write(clients[fd].partner, buf, strlen(buf));
printf("server => client(cfd=%d): %s\n", clients[fd].partner, buf);
sprintf(buf, " (%s to %s)", clients[fd].name, clients[clients[fd].partner].name);
write(clients[fd].partner, buf, strlen(buf));
} else {
write(fd, "Invalid input to protocol.", 26);
fprintf(stderr, "Invalid input to protocol.\n");
printf("Client socket(cfd=%d) is closed.\n", fd);
close(fd);
FD_CLR(fd, set);
}
}
cli.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
int main(void) {
printf("Hi, I am the client.\n");
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Socket(sfd=%d) is created.\n", sfd);
if (connect(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to connect");
exit(EXIT_FAILURE);
}
char buf[BUFFER_SIZE];
printf("client => server: (Enter ping) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
int chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "pong") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
printf("client => server: (Enter pang) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "pung. Enter your name.") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
printf("client => server: (Enter your name) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "Enter your age.") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
printf("client => server: (Enter your age) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "Enter your partner.") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
printf("client => server: (Enter your partner) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "Process completed. Start chatting.") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
if (fork() == 0) {
while (1) {
chunk = read(sfd, buf, BUFFER_SIZE - 1);
if (chunk > 0) {
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
}
}
} else {
while (1) {
printf("client => server: (Chat) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
}
}
close(sfd);
return 0;
}
serv.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define LISTEN_BACKLOG 5
#define MAX_FD_COUNT 50
#define MAX_NAME_LENGTH 20
#define MAX_AGE_LENGTH 5
#define MAX_CLIENT_COUNT 50
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
#define STATE_UNDEFINED 0
#define STATE_INIT 1
#define STATE_ASK_NAME 2
#define STATE_READY 3
#define STATE_ASK_PARTNER 4
#define STATE_CHAT 5
typedef struct client {
char name[MAX_NAME_LENGTH];
char age[MAX_AGE_LENGTH];
int partner;
} CLIENT;
void handle_protocol(int fd, fd_set* set, int* states, CLIENT* clients);
int main(void) {
printf("Hi, I am the server.\n");
struct sockaddr_in serv_addr, cli_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Server socket(sfd=%d) is created.\n", sfd);
if (bind(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to bind");
exit(EXIT_FAILURE);
}
if (listen(sfd, LISTEN_BACKLOG) == -1) {
perror("Fail to listen");
exit(EXIT_FAILURE);
}
socklen_t cli_addr_len = sizeof(cli_addr);
fd_set read_fds, temp_fds;
FD_ZERO(&read_fds);
FD_SET(sfd, &read_fds);
int states[MAX_FD_COUNT] = { STATE_UNDEFINED };
CLIENT clients[MAX_CLIENT_COUNT];
while (1) {
temp_fds = read_fds;
select(MAX_FD_COUNT, &temp_fds, NULL, NULL, NULL);
for (int fd = 0; fd < MAX_FD_COUNT; fd += 1) {
if (FD_ISSET(fd, &temp_fds)) {
if (fd == sfd) {
int cfd = accept(sfd, (struct sockaddr*) &cli_addr, &cli_addr_len);
if (cfd == -1) {
perror("Fail to accept");
exit(EXIT_FAILURE);
}
states[cfd] = STATE_INIT;
printf("Client socket(cfd=%d) is accepted.\n", cfd);
FD_SET(cfd, &read_fds);
} else {
handle_protocol(fd, &read_fds, states, clients);
}
}
}
}
return 0;
}
void handle_protocol(int fd, fd_set* set, int* states, CLIENT* clients) {
char buf[BUFFER_SIZE];
int chunk = read(fd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("client(cfd=%d) => server: %s\n", fd, buf);
int state = states[fd];
if (state == STATE_INIT && strcmp(buf, "hello") == 0) {
write(fd, "name?", 5);
printf("server => client(cfd=%d): name?\n", fd);
states[fd] += 1;
} else if (state == STATE_ASK_NAME && strlen(buf) > 0) {
strcpy(clients[fd].name, buf);
write(fd, "ready?", 6);
printf("server => client(cfd=%d): ready?\n", fd);
states[fd] += 1;
} else if (state == STATE_READY && strcmp(buf, "yes") == 0) {
strcpy(buf, "client list(");
for (int other_fd = 0; other_fd < MAX_FD_COUNT; other_fd += 1) {
if (fd != other_fd && states[other_fd] > STATE_ASK_NAME) {
strcat(buf, clients[other_fd].name);
strcat(buf, ", ");
}
}
if (buf[strlen(buf) - 2] == ',') {
buf[strlen(buf) - 2] = '\0';
}
strcat(buf, ")");
write(fd, buf, strlen(buf));
printf("server => client(cfd=%d): %s\n", fd, buf);
states[fd] += 1;
} else if (state == STATE_ASK_PARTNER && strlen(buf) > 0) {
for (int other_fd = 0; other_fd < MAX_FD_COUNT; other_fd += 1) {
if (fd != other_fd && states[other_fd] > STATE_ASK_NAME && strcmp(buf, clients[other_fd].name) == 0) {
clients[fd].partner = other_fd;
write(fd, "go", 2);
printf("server => client(cfd=%d): go\n", fd);
states[fd] += 1;
break;
}
}
} else if (state == STATE_CHAT && strlen(buf) > 0) {
write(clients[fd].partner, buf, strlen(buf));
printf("server => client(cfd=%d): %s\n", clients[fd].partner, buf);
} else {
write(fd, "Invalid input to protocol.", 26);
fprintf(stderr, "Invalid input to protocol.\n");
printf("Client socket(cfd=%d) is closed.\n", fd);
close(fd);
FD_CLR(fd, set);
}
}
cli.c
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
int main(void) {
printf("Hi, I am the client.\n");
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Socket(sfd=%d) is created.\n", sfd);
if (connect(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to connect");
exit(EXIT_FAILURE);
}
printf("client => server: hello\n");
write(sfd, "hello", 5);
char buf[BUFFER_SIZE];
int chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "name?") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
printf("client => server: (Enter your name) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "ready?") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
printf("client => server: (Enter yes) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
printf("client => server: (Enter your partner) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "go") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
if (fork() == 0) {
while (1) {
chunk = read(sfd, buf, BUFFER_SIZE - 1);
if (chunk > 0) {
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
}
}
} else {
while (1) {
printf("client => server: (Chat) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
}
}
close(sfd);
return 0;
}
ex1.c
#include <stdio.h>
void main() {
for(;;);
}
ex2.c
#include <stdio.h>
#include <signal.h>
void foo(int signum) {
printf("I am ok\n");
}
void main() {
signal(2, foo);
for(;;);
}
signal(15, foo);
하면 kill -15
로 죽지 않음kill -9
( = SIGKILL
)은 새로운 동작을 정의할 수 없어 항상 프로세스를 종료시킴#include <stdio.h>
#include <signal.h>
void foo(int signum) {
printf("I am ok\n");
}
void main() {
signal(2, foo);
signal(15, foo);
signal(1, foo);
for(;;);
}
#include <stdio.h>
#include <signal.h>
void foo(int signum) {
printf("I am ok\n");
}
void main() {
if(fork()==0) for(;;);
else {
if(fork()==0) for(;;);
}
for(;;);
}
#include <stdio.h>
#include <signal.h>
void foo(int signum) {
printf("I am ok\n");
}
void wait_parent() {
wait();
}
void main() {
signal(17, wait_parent);
if(fork()==0) for(;;);
else {
if(fork()==0) for(;;);
}
for(;;);
}
serv.c
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define LISTEN_BACKLOG 5
#define MAX_FD_COUNT 50
#define MAX_FILENAME_LENGTH 100
#define MAX_CLIENT_COUNT 50
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
#define STATE_UNDEFINED 0
#define STATE_INIT 1
#define STATE_ASK_FILENAME 2
#define STATE_READY 3
typedef struct client {
char reqeusted_filename[MAX_FILENAME_LENGTH];
} CLIENT;
void handle_protocol(int fd, fd_set* set, int* states, CLIENT* clients);
int main(void) {
printf("Hi, I am the FTP server.\n");
struct sockaddr_in serv_addr, cli_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Server socket(sfd=%d) is created.\n", sfd);
if (bind(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to bind");
exit(EXIT_FAILURE);
}
if (listen(sfd, LISTEN_BACKLOG) == -1) {
perror("Fail to listen");
exit(EXIT_FAILURE);
}
socklen_t cli_addr_len = sizeof(cli_addr);
fd_set read_fds, temp_fds;
FD_ZERO(&read_fds);
FD_SET(sfd, &read_fds);
int states[MAX_FD_COUNT] = { STATE_UNDEFINED };
CLIENT clients[MAX_CLIENT_COUNT];
while (1) {
temp_fds = read_fds;
select(MAX_FD_COUNT, &temp_fds, NULL, NULL, NULL);
for (int fd = 0; fd < MAX_FD_COUNT; fd += 1) {
if (FD_ISSET(fd, &temp_fds)) {
if (fd == sfd) {
int cfd = accept(sfd, (struct sockaddr*) &cli_addr, &cli_addr_len);
if (cfd == -1) {
perror("Fail to accept");
exit(EXIT_FAILURE);
}
states[cfd] = STATE_INIT;
printf("Client socket(cfd=%d) is accepted.\n", cfd);
FD_SET(cfd, &read_fds);
} else {
handle_protocol(fd, &read_fds, states, clients);
}
}
}
}
return 0;
}
void handle_protocol(int fd, fd_set* set, int* states, CLIENT* clients) {
char buf[BUFFER_SIZE];
int chunk = read(fd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("client(cfd=%d) => server: %s\n", fd, buf);
int state = states[fd];
if (state == STATE_INIT && strcmp(buf, "hello") == 0) {
write(fd, "file name?", 10);
printf("server => client(cfd=%d): file name?\n", fd);
states[fd] += 1;
} else if (state == STATE_ASK_FILENAME && strlen(buf) > 0) {
strcpy(clients[fd].reqeusted_filename, buf);
write(fd, "ready?", 6);
printf("server => client(cfd=%d): ready?\n", fd);
states[fd] += 1;
} else if (state == STATE_READY && strcmp(buf, "yes") == 0) {
int res_fd = open(clients[fd].reqeusted_filename, O_RDONLY);
if (res_fd == -1) {
char* response = "Fail to open the file.";
write(fd, response, strlen(response));
printf("server => client: %s\n", response);
buf[0] = -1;
write(fd, buf, 1);
return;
}
printf("server => client(cfd=%d): ", fd);
fflush(stdout);
while ((chunk = read(res_fd, buf, BUFFER_SIZE))) {
write(fd, buf, chunk);
write(STDOUT_FILENO, buf, chunk);
}
buf[0] = -1;
write(fd, buf, 1);
printf("\n");
close(res_fd);
printf("Client socket(cfd=%d) is closed.\n", fd);
close(fd);
FD_CLR(fd, set);
} else {
write(fd, "Invalid input to protocol.", 26);
fprintf(stderr, "Invalid input to protocol.\n");
printf("Client socket(cfd=%d) is closed.\n", fd);
close(fd);
FD_CLR(fd, set);
}
}
cli.c
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 100
#define MAX_FILENAME_LENGTH 100
#define SERV_ADDR "165.246.38.152"
#define SERV_PORT 13579
int main(void) {
printf("Hi, I am the FTP client.\n");
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
if (inet_aton(SERV_ADDR, &serv_addr.sin_addr) == 0) {
fprintf(stderr, "Invalid Address\n");
exit(EXIT_FAILURE);
}
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1) {
perror("Fail to create");
exit(EXIT_FAILURE);
}
printf("Socket(sfd=%d) is created.\n", sfd);
if (connect(sfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) {
perror("Fail to connect");
exit(EXIT_FAILURE);
}
printf("client => server: hello\n");
write(sfd, "hello", 5);
char buf[BUFFER_SIZE];
int chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "file name?") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
char filename[MAX_FILENAME_LENGTH];
printf("client => server: (Enter file name) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
buf[strlen(buf) - 1] = '\0';
strcpy(filename, buf);
write(sfd, buf, strlen(buf));
chunk = read(sfd, buf, BUFFER_SIZE - 1);
buf[chunk] = '\0';
printf("server => client: %s\n", buf);
if (strcmp(buf, "ready?") != 0) {
fprintf(stderr, "Error occurred by the protocol.\n");
close(sfd);
exit(EXIT_FAILURE);
}
printf("client => server: (Enter yes) ");
fgets(buf, BUFFER_SIZE - 1, stdin);
write(sfd, buf, strlen(buf) - 1);
int res_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 00777);
if (res_fd == -1) {
fprintf(stderr, "Fail to open the file.\n");
exit(EXIT_FAILURE);
}
printf("server => client: ");
fflush(stdout);
while (1) {
chunk = read(sfd, buf, BUFFER_SIZE);
if (buf[chunk - 1] == -1) {
write(res_fd, buf, chunk - 1);
write(STDOUT_FILENO, buf, chunk - 1);
break;
} else {
write(res_fd, buf, chunk);
write(STDOUT_FILENO, buf, chunk);
}
}
printf("\n");
close(res_fd);
close(sfd);
return 0;
}