/*
select 함수를 이용한 채팅 서버
*/
#include "/home/jinyedge/lib/c/edge_lib.h"
#include "/home/jinyedge/lib/c/edge_linux.h"
/*-----------------------*/
#define BUF_LEN 2048
#define MAX_GUEST 20
typedef struct _Guest{
char name[20];
int sock;
} Guest;
typedef struct _Lobby{
Guest *guest[MAX_GUEST];
int n_guest;
int guest_cnt;
} Lobby;
/*-----------------------*/
fd_set read_fds;
Lobby lobby;
/*-----------------------*/
void lobby_exit(int conn);
void lobby_talk2all(char buf[], int guest_idx);
Guest * get_new_guest(int sock);
/*-----------------------*/
int main(void){
int sersock, clnsock;
int n_fds;
int i, k, r_code;
struct sockaddr_in client_addr;
size_t size;
char buf[BUF_LEN];
/*서버 소켓 생성*/
sersock = get_server_sock(8040);
/*접속대기*/
if(listen(sersock, 5) < 0){
perror ("listen");
exit(EXIT_FAILURE);
}
printf("wating...\n");
/*로비 구조체를 초기화한다.*/
for(i = 0; i < MAX_GUEST; i++){
lobby.guest[i] = NULL;
}
lobby.n_guest = 0;
lobby.guest_cnt = 0;
/*read_fds 를 초기화*/
FD_ZERO(&read_fds);
while(1){
/*소켓번호를 fs_set 구조체에 지정한다.*/
FD_SET(sersock, &read_fds);
for(i = 0; i < MAX_GUEST; i++){
if(lobby.guest[i] != NULL){FD_SET(lobby.guest[i]->sock, &read_fds);}
}
/*select() 호출*/
if((select(FD_SETSIZE, &read_fds, (fd_set *)0, (fd_set *)0
, (struct timeval *)0)) < 0 ){
perror("select");
exit(EXIT_FAILURE);
}
/*연결요청을 처리한다.*/
if(FD_ISSET(sersock, &read_fds)){
size = sizeof(client_addr);
clnsock = accept(sersock, (struct sockaddr *)&client_addr, &size);
if(clnsock > -1){
lobby.guest[clnsock] = get_new_guest(clnsock);
lobby.guest_cnt++;
printf("Server: connected from host %s, port %hd. \n"
, inet_ntoa(client_addr. sin_addr)
, ntohs(client_addr. sin_port));
}
}
/*메시지를 처리한다.*/
for(i = 0; i < MAX_GUEST; i++){
if(lobby.guest[i] == NULL){continue;}
if(FD_ISSET(lobby.guest[i]->sock, &read_fds)){
if(sock_recv(lobby.guest[i]->sock, buf, BUF_LEN) > 0){
printf("Received: %s: %s\n"
, lobby.guest[i]->name, buf);
lobby_talk2all(buf, i);
}
else{lobby_exit(i);}
}
}
}
close(sersock);
}
/*-----------------------*/
void lobby_exit(int n){
FD_CLR(lobby.guest[n]->sock, &read_fds);
close(lobby.guest[n]->sock);
free(lobby.guest[n]);
lobby.guest[n] = NULL;
lobby.n_guest--;
}
/*-----------------------*/
void lobby_talk2all(char buf[], int guest_idx){
int i;
char w_buf[2048];
sprintf(w_buf, "%s: %s", lobby.guest[guest_idx]->name, buf);
for(i = 0; i < MAX_GUEST; i++){
if(lobby.guest[i] != NULL){
if(sock_send(lobby.guest[i]->sock, w_buf) < 0){lobby_exit(i);}
}
}
}
/*-----------------------*/
Guest * get_new_guest(int sock){
Guest *temp;
temp = (Guest *)malloc(sizeof(Guest));
sprintf(temp->name, "guest%d", lobby.guest_cnt);
temp->sock = sock;
return temp;
}
#include "/home/jinyedge/lib/c/edge_lib.c"
#include "/home/jinyedge/lib/c/edge_linux.c"
'UNIX_LINUX_C_C++' 카테고리의 다른 글
[공유메모리] 데이터 넣는 방법 (0) | 2011.10.16 |
---|---|
dialogic programming example - async mode (0) | 2011.10.16 |
날짜,pthread,도메인 (0) | 2011.10.16 |
[펌] C 에서의 문자열 (0) | 2011.10.16 |
[펌] str error result (0) | 2011.10.16 |