현재강좌 : UNIX 소켓 응용 프로그래밍 이전 4.2 채팅 서버 프로그램 다음: 4.4 멀티서버


4.3 채팅 클라이언트 프로그램

4.3.1 프로그램 개요

▶ 채팅 클라이언트 프로그램(chat_client.c)은 사용자의 입력 메시지를 서버로 전송하고, 서버가 보내온 모든 메시지를 사용자 화면에 출력한다.

▶ 즉, 3.1절의 토크 클라이언트 프로그램 talk_client.c와 유사한 동작을 한다.

▶ 그러나 talk_client.c에서는 사용자의 키보드 입력 처리와 수신 메시지 출력 두 가지 일을 동시에 수행하기 위해서 fork()를 이용하여 두 개의 프로세스를 만들어 각 프로세스가 이 두 가지 일을 담당하였으나, chat_client.c에서는 chat_server.c에서와 같이 select() 시스템 콜을 이용하여 소켓을 비동기 모드로 바꾸어 두 가지 입출력을 하나의 프로세스에서 처리하도록 구현하였다.

▶ chat_client.c가 수행되기 위하여는 4.2절에서 설명한 채팅 서버 프로그램 chat_server.c가 서버에서 먼저 실행되어야 하며 chat_server.c가 사용하는 포트번호와 서버의 IP 주소를 클라이언트에서 알고 있어야 한다.

▶ 또한 클라이언트에서는 채팅 참가자의 이름을 모든 메시지 앞에 붙여서 서버로 전송하여야 하기 때문에 자신의 이름을 프로그램 실행시 입력하도록 하였다.

chat_client server_IP server_Port my_name

▶위에서 server_IP 채팅 서버의 IP 주소 (dotted deci- mal)이고 server_Port 채팅 서버 프로그램(chat_server .c) 실행시 지정한 포트번호이며 my_name 채팅에서 사용할 자신의 이름이다.

▶ 아래는 chat_client.c의 실행 예이다.

# chat_client 203.252.65.3 4001 철수

접속에 성공했습니다..

대화방에 오신걸 환영합니다...

4.3.2 프로그램 주요부분 설명

▶ chat_client.c에서는 먼저 채팅 메시지 앞에 항상 붙여서 전송할 자신의 이름(argv[3])을 구조체 Name에 기록해 둔다.

struct Name {

char n[20]; /* 채팅에서 사용할 이름*/

int len; /* 이름의 실제 크기 */

} name;

/* 참가자 이름을 Name 구조체에 기록 */

sprintf(name.n, "[%s]", argv[3]);

name.len = strlen(name.n);

▶ chat_client.c에서 select()를 호출하려면 먼저 fd_set 구조체를 만들어야 하는데 chat_client.c에서는 읽기에 대한 I/O만 확인하면 되므로 fd_set 구조체로 read_fds 하나만 선언한다.

▶ FD_ZERO(&read_fds)를 호출하여 read_fds의 모든 소켓번호를 disable시킨다.

▶ 다음에는 I/O 변화에 관심을 갖는 소켓번호(파일기술자)들을 세트하여야 하는데, chat_client.c에서는 키보드 입력을 위한 파일기술자 0과 서버와 접속되어 있는 소켓 s 두 개의 파일기술자가 있다.

▶ 따라서 다음과 같이 FD_SET를 사용하면 된다.

fd_set read_fds; /* 읽기 변화를 감지하기 위한 fd_set 구조체 선언 */

FD_ZERO(&read_fds) /* 초기화 */

FD_SET(0, &read_fds); /* 키보드 입력용 파일기술자(0) 세트 */

FD_SET(s, &read_fds); /* 서버와 연결된 소켓번호(s) 세트 */

▶ select()를 호출할 때, read_fds를 select()의 두번째 인자(즉, 읽기 변화 감지용 fd_set)로 지정하고, 세번째와 네번째 인자 즉, 쓰기 및 예외발생에 해당하는 fd_set는 NULL로 지정한다.

▶ 한편 select() 문의 첫번째 인자로 사용할 '최대 소켓번호 +1'의 값으로는 s+1을 사용하였다.

select(nfds, &read_fds, (fd_set *)0, (fd_set *)0, (struct timeval *)0);

▶ select()가 리턴되었을 때, read_fds 내의 소켓번호 s 값이 세트되어 있다면 서버에서 메시지를 보내온 것이므로 이 메시지를 읽어 화면에 출력한다.

▶ 파일기술자 0이 세트된 경우는 자신의 키보드 입력이 발생한 것이므로 이 메시지를 서버에게 전송하면 된다.

if (FD_ISSET(s, &read_fds)) /* 서버가 보내오는 메시지를 수신하여 출력 */

if (FD_ISSET(0, &read_fds)) /* 키보드 입력 데이터를 서버로 전송 */

chat_client.c 프로그램 리스트


현재강좌 : UNIX 소켓 응용 프로그래밍 이전 4.2 채팅 서버 프로그램 다음: 4.4 멀티서버