echo 서버와 클라이언트를 만들어야 해서, 우선적으로 새로운 폴더를 만들었다.
echo 디렉토리 안에, client와 server 디렉토리를 만들어주었고, 각각 Makefile 을 만들어서 make 명령어로 실행파일을 만들 수 있게 했다.
위에 tree를 보면, client 디렉토리 안에 연두색 echoclient 와 server 디렉토리 안에 연두색 echoserver는 실행 파일이다.
두 개의 터미널을 열어서 먼저 echoserver을 실행시키고, echoclient 를 실행시켜 echo 가 잘되는지 확인했다.
그리고 직접 디버그모드를 통해 클라이언트와 서버 중에 어떠한 코드가 먼저 실행되는지 확인하면서 공부했다.
서버 실행 방법(in terminal)
$ 실행파일 포트번호
$ minpic/webproxy-lab/echo/server$ ./echoserver 52184
client 실행 방법 (in terminal)
$ 실행파일 퍼블릭IP 포트번호
$ minpic/webproxy-lab/echo/client$ ./echoclient 52.199.9.231 52184
echo 서버와 클라이언트 코드는 컴퓨터시스템 책의 나와있는 코드로 작성하였다.
주석을 통해서 순서를 적어놓았다.
echoserver.c
#include "../csapp.h"
void echo (int connfd);
int main(int argc, char **argv){
int listenfd, connfd;
socklen_t clientlen;
struct sockaddr_storage clientaddr;
char client_hostname[MAXLINE], client_port[MAXLINE];
if(argc != 2){
fprintf(stderr, "usage: %s <port>\n", argv[0]); // 서버 실행시 포트 번호 지정
exit(0);
}
listenfd = Open_listenfd(argv[1]); // 1. socket(), bind(), listen() 서버 열기
while(1) {
clientlen = sizeof(struct sockaddr_storage);
connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen); // 3. client accept!
Getnameinfo((SA *) &clientaddr, clientlen, client_hostname, MAXLINE,
client_port, MAXLINE, 0); // 4. client 정보 가져오기
printf("Connected to (%s, %s)\n", client_hostname, client_port);
echo(connfd); // 8. client 에서 받은 값을 다시 client 보내주기
Close(connfd);
}
exit(0);
}
echoclient.c
#include "../csapp.h"
int main(int argc, char **argv){
int clientfd;
char *host, *port, buf[MAXLINE];
rio_t rio;
if(argc != 3){
fprintf(stderr, "usage: %s <host> <port>\n", argv[0]);
exit(0);
}
host = argv[1];
port = argv[2];
// ubuntu: 52184
clientfd = Open_clientfd(host, port); // 2. socket(), connect() 서버 연결
Rio_readinitb(&rio, clientfd); // 5. RIO 패키지를 사용하여 clientfd로부터 읽기 위한 버퍼를 초기화.
while (Fgets(buf, MAXLINE, stdin) != NULL){ // 6. 사용자로 부터 입력 값 받고
Rio_writen(clientfd, buf, strlen(buf)); // 7. 입력 값을 서버 전달
Rio_readlineb(&rio, buf, MAXLINE); // 9. 서버에서 보내준 값 읽기
Fputs(buf, stdout); // 10. 읽은 값을 터미널에 보여주기
}
Close(clientfd);
exit(0);
}