csapp.c 에 대한 내용은 이전 hostinfo 를 참고
echo 는 client가 server에 보낸 정보를 server가 받고 다시 client에게 돌려줌
그래서 echo임
아래는 echo 관련 코드 분석
echoserveri.c
#include "csapp.h"
void echo(int connfd);
void echo(int connfd){
size_t n;
char buf[MAXLINE];
rio_t rio;
Rio_readinitb(&rio, connfd); // open한 식별자마다 한 번 호출, 식별자 connfd를 주소 rio에 위치한 읽기 버퍼와 연결
while((n=Rio_readlineb(&rio, buf, MAXLINE)) != 0){ // rio에서 얻은 값을 buf에 복사함
printf(" server received %d bytes\n", (int)n);
Rio_writen(connfd, buf, n); // buf의 값을 connfd에 복사함
}
}
int main(int argc, char **argv){
/* 선언부 */
int listenfd, connfd;
socklen_t clientlen;
struct sockaddr_storage clientaddr; /* Enough space for any address */
char client_hostname[MAXLINE], client_port[MAXLINE];
if(argc !=2){
fprintf(stderr, "usage: %s <domain name>\n", argv[0]);
exit(0);
}
listenfd = Open_listenfd(argv[1]); // open_listenfd 함수를 사용해서 server 소켓을 listenfd로 만들어서 대기함
while (1){ // EOF가 들어오기 전까지 계속 돌음
clientlen = sizeof(struct sockaddr_storage); // clientlen 은 sockaddr_storage 구조체의 크기만큼
connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen); // listenfd가 clinentfd를 만나면 accept가 되고 새로운 식별자를 connfd에 return 함
Getnameinfo((SA *)&clientaddr, clientlen, client_hostname, MAXLINE, client_port, MAXLINE, 0); // clientaddr와 clientlen을 이용해 client_hostname, client_port를 만들어냄
printf("Connected to (%s %s)\n", client_hostname, client_port); // 그들을 출력
echo(connfd); // echo 함수에 connfd 를 넣어서 echo 함수 돌림 --> 여기서 buf에 connfd에 복사함
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];
clientfd = Open_clientfd(host, port); // open_clientfd 함수를 이용해서 소켓을 client fd로 만듦
Rio_readinitb(&rio, clientfd); // clientfd에 rio의 주소를 연결
while (Fgets(buf, MAXLINE, stdin) != NULL){ // 표준 입력 스트림을 사용해서 buf 에서 MAXLINE 크기 만큼 읽어오고
Rio_writen(clientfd, buf, strlen(buf)); // 연결된 주소 clientfd 에 buf를 strlen(buf) 만큼 복사해 넣고
Rio_readlineb(&rio, buf, MAXLINE); // rio에 있는 값을 buf에 복사해넣음 MAXLINE 만큼
Fputs(buf, stdout); // 표준 출력 스트림에 buf를 넣음
}
Close(clientfd); // 메모리 누수를 막기 위해서 clientfd를 닫음
exit(0); // 함수 밖으로 나감
}
echo.c
#include "csapp.h"
void echo(int connfd){
size_t n;
char buf[MAXLINE];
rio_t rio;
Rio_readinitb(&rio, connfd); // open한 식별자마다 한 번 호출, 식별자 connfd를 주소 rio에 위치한 읽기 버퍼와 연결
while((n=Rio_readlineb(&rio, buf, MAXLINE)) != 0){ // rio에서 얻은 값을 buf에 복사함
printf(" server received %d bytes\n", (int)n);
Rio_writen(connfd, buf, n); // buf의 값을 connfd에 복사함
}
}