#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <string.h>
#define MAXLINE 99999
#define MAX_SOCK 64
int getmax(int);
void disconnect_client(int); /* 채팅 탈퇴 처리 함수 */
void my_signal(int signo); /* 새로운 시그널 처리 함수 선언 */
int maxfdp1; /* 최대 소켓번호+1 */
int num_chat = 0; /* 채팅 참가자 수 */
int ____main_socket; /* 초기 소켓 */
int ____client_socket[MAX_SOCK]; /* 채팅에 참가자 소켓번호 목록 */
int main(int argc, char *argv[])
{
char rline[MAXLINE+1];
int i, j, kk;
int recv_len;
int client_fd, clilen;
int recv_len_sum=0;
int recv_seq_sum=0;
int recv_divide;
fd_set read_fds; /* 일기 감지할 소켓번호 구조체 */
struct sockaddr_in client_addr, server_addr;
if (argc != 2) {
printf("Usage: %s port\n", argv[0]);
exit(0);
}
/* 초기소켓 생성 */
if ((____main_socket = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
printf("Server: Can't open stream socket.");
exit(0);
}
/* server_addr 구조체의 내용 세팅 */
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(atoi(argv[1]));
if (bind(____main_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
printf("Server: Can't bind local address.\n");
exit(0);
}
if (signal(SIGINT, my_signal) == SIG_ERR) { /* Ctrl+C */
printf("Server: signal(SIGINT) error\n");
exit(0);
}
if (signal(SIGTERM, my_signal) == SIG_ERR) { /* software termination */
printf("Server: signal(SIGTERM) error\n");
exit(0);
}
if (signal(SIGQUIT, my_signal) == SIG_ERR) { /* Ctrl+\ */
printf("Server: signal(SIGQUIT) error\n");
exit(0);
}
/* 클라이언트로부터 연결요청을 기다림 */
listen(____main_socket, 5); /* backlog = 5 */
maxfdp1 = ____main_socket + 1; /* 최대 소켓번호+1 */
while (1)
{
FD_ZERO(&read_fds);
FD_SET(____main_socket, &read_fds);
for (kk=0; kk < num_chat; kk++)
{
FD_SET(____client_socket[kk], &read_fds);
}
maxfdp1 = getmax(____main_socket) + 1; /* maxfdp1 재 계산 */
if (select(maxfdp1, &read_fds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) {
printf("Server: select error <= 0\n");
break;
}
if (FD_ISSET(____main_socket, &read_fds))
{
clilen = sizeof(client_addr);
client_fd = accept(____main_socket, (struct sockaddr *)&client_addr, &clilen);
if (client_fd == -1)
{
printf("Server: accept error\n");
break;
}
____client_socket[num_chat] = client_fd;
num_chat++;
}
for (kk=0; kk < num_chat; kk++)
{
if (FD_ISSET(____client_socket[kk], &read_fds))
{
if ((recv_len = recv(____client_socket[kk], rline, MAXLINE, 0)) <= 0)
{
disconnect_client(kk); /* abrupt exit */
continue;
}
rline[recv_len] = '\0';
recv_divide = recv_len / getfromframeid(rline, recv_len);
recv_seq_sum++;
recv_len_sum = recv_len_sum + recv_divide;
printf("SESSION SEQ[%07d]/RECV LENGTH[%07d]/DIVIDE[%07d]/REAL SUM[%07d]/SEQ SUM[%07d]\n",
kk+1, recv_len,
recv_divide, recv_len_sum, recv_seq_sum);
}
}
} /* while */
my_signal(SIGIO);
}
/* 채팅 탈퇴 처리 */
void disconnect_client(int i) {
struct sockaddr_in client_addr;
close(____client_socket[i]);
if (i != num_chat-1)
____client_socket[i] = ____client_socket[num_chat-1];
num_chat--;
printf("[function]disconnect_client>>[%d]\n", num_chat);
}
/* ____client_socket[] 내의 최대 소켓번호 얻기(초기치는 k) */
int getmax(int k) {
int max = k;
int r;
for (r=0; r < num_chat; r++)
if (____client_socket[r] > max)
max = ____client_socket[r];
return max;
}
/* 시그널 처리 함수 정의 */
void my_signal(int signo) {
int i;
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
/* 모든 열려있는 소켓을 닫는다 */
close(____main_socket);
for (i=0; i < num_chat; i++)
close(____client_socket[i]);
exit(0);
}
int getfromframeid(char *tmp, int len)
{
int kk=0;
if(memcmp(tmp, "A0011", 5) == 0) kk=800;
return kk;
}
'통신 > SELECT(TCP)' 카테고리의 다른 글
KOSCOM DATA,SEND,SELECT MODEL CLIENT (0) | 2020.08.25 |
---|---|
WINDOWS,CLIENT,THREAD(FILE READ SEND),BASIC(RECV),FILE SAVE(DIFF) (0) | 2019.10.29 |
WINDOWS,SERVER,SELECT(FILE RECV),BASIC(SEND),FILE SAVE(DIFF) (0) | 2019.10.29 |
WINDOWS,SERVER,SELECT(FILE RECV),BASIC(SEND) (0) | 2019.10.29 |
WINDOWS,CLIENT,THREAD(FILE READ SEND),BASIC(RECV) (0) | 2019.10.29 |