리눅스 채팅 서버의 다음 소스에서 어떻게하면 방 갯수와 접속자를 무제한으로 바꿀 수 있는지 조언좀 해주십시오.
/*
정적인 유저 수와 방 개수의 한계를 가지는 채팅서버
- 각 방이 가지는 유저에 대해서는 구조체로 관리
동시처리에 대해서는 select이용
*/
#include
#include
#include
#include
#include
#include
/*접속 포트 설정*/
#define SERVER_PORT 3000
/*
유저가 가질수 있는 데이터 : 소켓 기술자 / 대화명(귓속말등 기타 기능 추가시 서버에서 관리)
*/
struct user_node
{
int user_sockfd;
};
/*
각 방의 인원은 5명이지만 Linked List로 유저에 대한 동적인 할당이 필요
*/
struct room_node
{
char room_name[10];
struct user_node user_list[5];
int user_count;
};
int Socket(int family, int type, int protocol);
void Bind (int sockfd, const struct sockaddr * socketaddr, socklen_t addrlen);
void Listen(int sockfd, int backlog);
int Accept(int sockfd, struct sockaddr* cliaddr, socklen_t *addrlen);
int main(void)
{
/*채팅에서의 방을 3개로 설정*/
struct room_node roomlist[3];
int server_socket;
int client_socket;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int addrsize, msgsize;
char BUFF[1024] = {0};
fd_set readfd;
int maxfd;
int room_index;
int user_index;
int tempsockfd;
int temp_user_count;
/*각 방에 대한 방이름 초기화*/
strcpy(roomlist[0].room_name,"room1");
strcpy(roomlist[1].room_name,"room2");
strcpy(roomlist[2].room_name,"room3");
/*각 방의 접속 사용사 수를 초기화*/
roomlist[0].user_count = 0;
roomlist[1].user_count = 0;
roomlist[2].user_count = 0;
/*1. 서버소켓생성*/
server_socket = Socket(AF_INET, SOCK_STREAM, 0);
/*서버 IP및 포트 설정*/
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
memset(&(server_addr.sin_zero), 0, 8);
Bind(server_socket, (struct sockaddr*)&server_addr, sizeof(struct sockaddr));
Listen(server_socket, 0);
FD_ZERO(&readfd);
maxfd = server_socket;
while(1)
{
/*서버에접속한 클라이언트 소켓 기술자[각 방의 유저구조체포함]를 fd_set에 설정*/
FD_SET(server_socket, &readfd);
for (room_index = 0; room_index < 3; room_index++)
{
for (user_index = 0; user_index < roomlist[room_index].user_count; user_index++)
{
tempsockfd = roomlist[room_index].user_list[user_index].user_sockfd;
FD_SET(tempsockfd, &readfd);
if (tempsockfd > maxfd)
maxfd = tempsockfd;
}
}
maxfd = maxfd + 1;
select(maxfd, &readfd, NULL, NULL,NULL);
/*서버로의 접속이 있는 클라이언트에 대한 처리*/
if (FD_ISSET(server_socket, &readfd))
{
addrsize = sizeof(struct sockaddr_in);
client_socket = Accept(server_socket, (struct sockaddr*)&server_addr, &addrsize);
msgsize = read(client_socket, BUFF, sizeof(BUFF));
if (msgsize <=0)
{
printf("Enter user Error\n");
continue;
}
printf("Receive Message:%s\n", BUFF);
/*각 방이 5명으로 제한되어있으므로 해당 유저인원 체크*/
if (BUFF[0] == '1')
{
printf("Login Room1 Count:%d\n", roomlist[0].user_count);
if (roomlist[0].user_count == 5)
{
strcpy(BUFF, "User Count Overflow Error");
write(client_socket, BUFF, strlen(BUFF));
close(client_socket);
continue;
/*인원초과*/
}
roomlist[0].user_list[roomlist[0].user_count].user_sockfd = client_socket;
roomlist[0].user_count++;
strcpy(BUFF, "ConnectOK");
write(client_socket, BUFF, strlen(BUFF));
}
else if(BUFF[0] == '2')
{
if (roomlist[1].user_count == 5)
{
strcpy(BUFF, "User Count OverFlow Error");
write(client_socket, BUFF, strlen(BUFF));
close(client_socket);
continue;
/*인원초과*/
}
roomlist[1].user_list[roomlist[1].user_count].user_sockfd = client_socket;
roomlist[1].user_count++;
strcpy(BUFF, "ConnectOK");
write(client_socket, BUFF, strlen(BUFF));
}
else if(BUFF[0] == '3')
{
if (roomlist[2].user_count == 5)
{
strcpy(BUFF, "User Count OverFlow Error");
write(client_socket, BUFF, strlen(BUFF));
close(client_socket);
continue;
/*인원초과*/
}
roomlist[2].user_list[roomlist[2].user_count].user_sockfd = client_socket;
roomlist[2].user_count++;
strcpy(BUFF, "ConnectOK");
write(client_socket, BUFF, strlen(BUFF));
}
continue;
}
/*
각 방에 속한 모든 유저들의 소켓 기술자의 변화를 감지하여
해당 수신 데이터에 대한 응답을 같은 방에 있는 유저에 한해서 송신
*/
for (room_index = 0; room_index < 3; room_index++)
{
for (user_index = 0; user_index < roomlist[room_index].user_count; user_index++)
{
if (FD_ISSET(roomlist[room_index].user_list[user_index].user_sockfd, &readfd))
{
tempsockfd = roomlist[room_index].user_list[user_index].user_sockfd;
msgsize = read(tempsockfd, BUFF,sizeof(BUFF));
if (msgsize <= 0)
{
if (user_index == roomlist[room_index].user_count)
{
close(roomlist[room_index].user_list[user_index].user_sockfd);
roomlist[room_index].user_count--;
}
else if (user_index < roomlist[room_index].user_count)
{
close(roomlist[room_index].user_list[user_index].user_sockfd);
for (temp_user_count = user_index; temp_user_count < roomlist[room_index].user_count; temp_user_count++)
{
roomlist[room_index].user_list[temp_user_count] = roomlist[room_index].user_list[temp_user_count+1];
}
roomlist[room_index].user_count--;
}
}
else
{
printf("Receive Message=>%s\n", BUFF, msgsize);
for (temp_user_count = 0; temp_user_count < roomlist[room_index].user_count; temp_user_count++)
{
msgsize = strlen(BUFF);
write(roomlist[room_index].user_list[temp_user_count].user_sockfd, BUFF,msgsize);
}
}
}
}
}
}
return 0;
}
int Socket(int family, int type, int protocol)
{
int result = 0;
result = socket(family, type, protocol);
if (result == -1)
{
printf("Socket Contructing Error\n");
exit(0);
}
return result;
}
void Bind(int sockfd, const struct sockaddr * socketaddr, socklen_t addrlen)
{
int result = 0;
result = bind(sockfd, socketaddr, addrlen);
if (result == -1)
{
printf("Socket Binding Error\n");
exit(0);
}
else
{
printf("Success Binding\n");
}
}
void Listen(int sockfd, int backlog)
{
int result = 0;
result = listen(sockfd, backlog);
if (result == -1)
{
printf("Listening Error\n");
exit(0);
}
else
{
printf("Success Listening\n");
}
}
int Accept(int sockfd, struct sockaddr* cliaddr, socklen_t *addrlen)
{
int result = 0;
result = accept(sockfd, cliaddr, addrlen);
if (result == -1)
{
printf("Accept Error\n");
exit(0);
}
else
{
printf("Success Accept\n");
}
return result;
}
(아무래도 code태그를
(아무래도 code태그를 사용하시는것이.. -ㅅ-)
그냥 단순하게 Linked List를 쓰면 됩니다...라고 할수 있겠죠....
c++이면 list 자료형을 쓰면 무진장 편한데...
c이기 때문에 아무래도 조금 고생하셔야겠습니다 ㅡㅡ;;
먼저 Linked List 자료형을 선언하시고,
여러가지 함수 ( insert( target, location, data ) , remove( target, location ) )를 만드신 다음,
정상적으로 작동하는지 확인하시고,,
room_node에
이런 선언을 추가해야겠고요,,,,
그리고 아래쪽에 사용자 추가하는 부분을 고치셔야 할겁니다.
간단하게 위에서 만든 insert함수를 써서 하시면 되겠네요.
또 전역으로
선언한 후에 역시 방 추가/제거는 간단하게 샤샥....
( 아무래도 이 문제의 핵심은 linked list인듯 하군요;;; )
여러가지 함수를 만드는게...
죄송하지만 좀더 구체적으로 알려주시면 안될까요?
어느 학교이신지
어느 학교이신지 궁금하군요. 제가 바로 지난주에 시험본 내용인데.
질답게시판에서 이후 두번째로 올리신걸 보니 많이 급하시군요.
친절하게도 예제소스에서 방법을 알려주고 있군요!
참고하세요.
http://gamedeveloper.co.kr/12
http://www.winapi.co.kr/clec/cpp2/19-2-1.htm
---
Make Better Life.
---
Make Better Life.
참고하시라는 사이트는 잘 보았습니다.
근데 기간이 얼마 남지 않아서 혼자 짜기에는 넉넉치 않아서 혹시라도 알고 계신다면 소스에 추가하는 방법좀 알려주세요.