- 에코 클라이언트의 입출 루틴 분할
- 입출력 루틴의 분할이 의미하는 바를 이해했으니 실제 코드상에서 입출력 루틴을 분할해보자 분할의 대상은 에코클라이언트이다. 다음 에코 클라이언트는 앞서 소개한 에코 서버인 예제 echo_mpserv.c와 함께 동작시키면된다 .
- echo_mpclient.c 예제
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUF_SIZE 30
void error_handling(const char *message);
void read_routine(int sock, char *buf);
void write_routine(int sock, char *buf);
int main(int argc, char *argv[])
{
int sock;
pid_t pid;
char buf[BUF_SIZE];
struct sockaddr_in serv_adr;
if(argc != 3){
printf("Usage : %s <IP> <port> \n", argv[0]);
exit(1);
}
sock = socket(PF_INET, SOCK_STREAM, 0);
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = inet_addr(argv[1]);
serv_adr.sin_port = htons(atoi(argv[2]));
if( connect(sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) == 1)
error_handling("connect() error!");
pid = fork();
if( pid == 0)
{
// 여기서 호출하는 write_Routine함수에는 데이터 출력에 관련된 코드만 존재한다.
// 반면 else문에서 호출하는 read_Routine함수에는 데이터 입력에 관련된 코드만 존재한다.
// 이렇듯 입력출력루틴을 구분해서 각각의 함수로 정의하는것은
// 구현의 편의를 가져다 준다.
write_routine(sock, buf);
}
else
{
read_routine(sock, buf);
}
close(sock);
return 0;
}
void read_routine(int sock, char *buf)
{
while(1)
{
int str_len = read(sock, buf, BUF_SIZE);
if( str_len == 0 )
return;
buf[str_len] = 0;
printf("Message from server: %s", buf);
}
}
void write_routine(int sock, char *buf)
{
while(1)
{
fgets(buf, BUF_SIZE, stdin);
if( !strcmp(buf,"q\n") || !strcmp(buf, "Q\n"))
{
// 서버로의 EOF전달을 위해서shutdown함수가 호출되어싿.
// 물론 아래의 return 문 실행 이후에 main함수 끝부분의 close함수 호출을 통해
// eof 의 전달을 기대할 수 잇지만 현재 fork함수호출을 통해서
// 파일 디스크립터가 복사된 상황이다그리고 이러한 상황에서는 한번의 close함수호출로
// EOF의 전달을 기대할 수 없다 따라서 반드시shutdown함수호출을통해서
// EOF의 전달을 별도로 명시해야한다.
shutdown(sock, SHUT_WR);
return;
}
write(sock, buf, strlen(buf));
}
}
void error_handling(const char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
'책 > 윤성우 TCPIP' 카테고리의 다른 글
11-01 프로세스간 통신의 기본 개념 (2) (0) | 2020.12.25 |
---|---|
11-01 프로세스간 통신의 기본 개념 (1) (0) | 2020.12.24 |
10-05 TCP의 입출력 루틴(Routine)분할 (0) | 2020.12.22 |
10-04 멀티태스킹 기반의 다중접속 서버(2) (0) | 2020.12.21 |
10-03 : 시그널 핸들링 (3) ~ 10-04 멀티태스킹 기반의 다중접속 서버(1) (0) | 2020.12.20 |