방갯수와 방인원을 무제한으로~!
작성자 정보
- 강길상 작성
- 작성일
컨텐츠 정보
- 1,801 조회
- 0 추천
- 목록
본문
방갯수와 방인원을 무제한으로 소스좀 다시 코딩할려고 합니다
조언 부탁드립니다.
/*
정적인 유저 수와 방 개수의 한계를 가지는 채팅서버
- 각 방이 가지는 유저에 대해서는 구조체로 관리
동시처리에 대해서는 select이용
*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include <unistd.h>
#include <stdio.h>
/*접속 포트 설정*/
#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
");
continue;
}
printf("Receive Message:%s
", BUFF);
/*각 방이 5명으로 제한되어있으므로 해당 유저인원 체크*/
if (BUFF[0] == '1')
{
printf("Login Room1 Count:%d
", 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
", 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
");
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
");
exit(0);
}
else
{
printf("Success Binding
");
}
}
void Listen(int sockfd, int backlog)
{
int result = 0;
result = listen(sockfd, backlog);
if (result == -1)
{
printf("Listening Error
");
exit(0);
}
else
{
printf("Success Listening
");
}
}
int Accept(int sockfd, struct sockaddr* cliaddr, socklen_t *addrlen)
{
int result = 0;
result = accept(sockfd, cliaddr, addrlen);
if (result == -1)
{
printf("Accept Error
");
exit(0);
}
else
{
printf("Success Accept
");
}
return result;
}
관련자료
-
이전
-
다음