목차
1. 채팅 서버 프로그램
1.1 채팅서버구조
1.2 select() 시스템콜
1.3 프로그램 주雅觀劇낯?
2. 채팅 클라이언트 프로그램
2.1 프로그램 개요
2.2 프로그램 주요부분 설명
1.1 채팅서버구조
1.2 select() 시스템콜
1.3 프로그램 주雅觀劇낯?
2. 채팅 클라이언트 프로그램
2.1 프로그램 개요
2.2 프로그램 주요부분 설명
본문내용
lient_addr);
client_fd = accept(s, (struct sockaddr *)&client_addr, &clilen);
if(client_fd != -1) {
// 채팅 클라이언트 목록에 추가
client_s[num_chat] = client_fd;
num_chat++;
send(client_fd, start, strlen(start), 0);
printf("%d번째 사용자 추가.\n",num_chat);
}
}
// 임의의 클라이언트가 보낸 메시지를 모든 클라이언트에게 방송
for(i = 0; i < num_chat; i++) {
if(FD_ISSET(client_s[i], &read_fds)) {
if((n = recv(client_s[i], rline, MAXLINE,0)) > 0) {
rline[n] = '\0';
// 종료문자 입력시 채팅 탈퇴 처리
if (exitCheck(rline, escapechar, 5) == 1) {
shutdown(client_s[i], 2);
if(i != num_chat-1) client_s[i] = client_s[num_chat-1];
num_chat--;
continue;
}
// 모든 채팅 참가자에게 메시지 방송
for (j = 0; j < num_chat; j++) send(client_s[j], rline, n, 0);
printf("%s", rline);
}
}
}
}
}
// 종료문자 확인 함수
int exitCheck(rline, escapechar, len)
char*rline;// 클라이언트가 전송한 메시지
char*escapechar;// 종료문자
intlen;
{
inti, max;
char*tmp;
max = strlen(rline);
tmp = rline;
for(i = 0; i
if (*tmp == escapechar[0]) {
if(strncmp(tmp, escapechar, len) == 0)
return 1;
} else
tmp++;
}
return -1;
}
chat_client.c
//--------------------------------------------------------------------
// 컴파일 : gcc -o chat_client chat_client.c -lsocket -lnsl
// 실행 : chat_client server_address port_num name
// 종료 : exit
// --------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#define MAXLINE 512
#define MAX_SOCK 128
char *escapechar = "exit";
char name[10]; // 채팅에서 사용할 이름
int main(int argc, char *argv[]) {
char line[MAXLINE], message[MAXLINE+1];
int n, pid;
struct sockaddr_in server_addr;
int maxfdp1;
int s; // 서버와 연결된 소켓번호
fd_set read_fds;
if(argc != 4) {
printf("사용법 : %s sever_IP port name \n", argv[0]);
exit(0);
}
// 채팅 참가자 이름 구조체 초기화
sprintf(name, "[%s]", argv[3]);
//소켓 생성
if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("Client : Can't open stream socket.\n");
exit(0);
}
// 채팅 서버의 소켓주소 구조체 server_addr 초기화
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
server_addr.sin_port = htons(atoi(argv[2]));
// 연결요청
if(connect(s, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
printf("Client : Can't connect to server.\n");
exit(0);
} else {
printf("서버에 접속되었습니다. \n");
}
maxfdp1 = s + 1;
FD_ZERO(&read_fds);
while(1) {
FD_SET(0, &read_fds);
FD_SET(s, &read_fds);
if(select(maxfdp1, &read_fds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) {
printf("select error\n");
exit(0);
}
if (FD_ISSET(s, &read_fds)) {
int size;
if ((size = recv(s, message, MAXLINE, 0)) > 0) {
message[size] = '\0';
printf("%s \n", message);
}
}
if (FD_ISSET(0, &read_fds)) {
if(fgets(message, MAXLINE, stdin)) {
sprintf(line, "%s %s", name, message);
if (send(s, line, strlen(line), 0) < 0)
printf("Error : Write error on socket.\n");
if (strstr(message, escapechar) != NULL ) {
printf("Good bye.\n");
close(s);
exit(0);
}
}
}
}
}
client_fd = accept(s, (struct sockaddr *)&client_addr, &clilen);
if(client_fd != -1) {
// 채팅 클라이언트 목록에 추가
client_s[num_chat] = client_fd;
num_chat++;
send(client_fd, start, strlen(start), 0);
printf("%d번째 사용자 추가.\n",num_chat);
}
}
// 임의의 클라이언트가 보낸 메시지를 모든 클라이언트에게 방송
for(i = 0; i < num_chat; i++) {
if(FD_ISSET(client_s[i], &read_fds)) {
if((n = recv(client_s[i], rline, MAXLINE,0)) > 0) {
rline[n] = '\0';
// 종료문자 입력시 채팅 탈퇴 처리
if (exitCheck(rline, escapechar, 5) == 1) {
shutdown(client_s[i], 2);
if(i != num_chat-1) client_s[i] = client_s[num_chat-1];
num_chat--;
continue;
}
// 모든 채팅 참가자에게 메시지 방송
for (j = 0; j < num_chat; j++) send(client_s[j], rline, n, 0);
printf("%s", rline);
}
}
}
}
}
// 종료문자 확인 함수
int exitCheck(rline, escapechar, len)
char*rline;// 클라이언트가 전송한 메시지
char*escapechar;// 종료문자
intlen;
{
inti, max;
char*tmp;
max = strlen(rline);
tmp = rline;
for(i = 0; i
if(strncmp(tmp, escapechar, len) == 0)
return 1;
} else
tmp++;
}
return -1;
}
chat_client.c
//--------------------------------------------------------------------
// 컴파일 : gcc -o chat_client chat_client.c -lsocket -lnsl
// 실행 : chat_client server_address port_num name
// 종료 : exit
// --------------------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#define MAXLINE 512
#define MAX_SOCK 128
char *escapechar = "exit";
char name[10]; // 채팅에서 사용할 이름
int main(int argc, char *argv[]) {
char line[MAXLINE], message[MAXLINE+1];
int n, pid;
struct sockaddr_in server_addr;
int maxfdp1;
int s; // 서버와 연결된 소켓번호
fd_set read_fds;
if(argc != 4) {
printf("사용법 : %s sever_IP port name \n", argv[0]);
exit(0);
}
// 채팅 참가자 이름 구조체 초기화
sprintf(name, "[%s]", argv[3]);
//소켓 생성
if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("Client : Can't open stream socket.\n");
exit(0);
}
// 채팅 서버의 소켓주소 구조체 server_addr 초기화
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
server_addr.sin_port = htons(atoi(argv[2]));
// 연결요청
if(connect(s, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
printf("Client : Can't connect to server.\n");
exit(0);
} else {
printf("서버에 접속되었습니다. \n");
}
maxfdp1 = s + 1;
FD_ZERO(&read_fds);
while(1) {
FD_SET(0, &read_fds);
FD_SET(s, &read_fds);
if(select(maxfdp1, &read_fds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) {
printf("select error\n");
exit(0);
}
if (FD_ISSET(s, &read_fds)) {
int size;
if ((size = recv(s, message, MAXLINE, 0)) > 0) {
message[size] = '\0';
printf("%s \n", message);
}
}
if (FD_ISSET(0, &read_fds)) {
if(fgets(message, MAXLINE, stdin)) {
sprintf(line, "%s %s", name, message);
if (send(s, line, strlen(line), 0) < 0)
printf("Error : Write error on socket.\n");
if (strstr(message, escapechar) != NULL ) {
printf("Good bye.\n");
close(s);
exit(0);
}
}
}
}
}