diff --git "a/c(select\354\213\234\355\227\230).c" "b/c(select\354\213\234\355\227\230).c" new file mode 100644 index 0000000..39de1d4 --- /dev/null +++ "b/c(select\354\213\234\355\227\230).c" @@ -0,0 +1,334 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BOARD_SIZE 5 +#define NAME_SIZE 10 +#define BUF_SIZE 100 + +void* send_msg(void* arg); +void* recv_msg(void* arg); +void* game_set(void* arg); + +void error_handling(char* mse); +void game_print(int any); +int bingo_check(int board[][BOARD_SIZE]); + +//게임관련 구조체로 묶을 변수 +struct Game{ +int Game_on; +int game_turn; +int my_turn; +int my_bingo; +int winFlag; //Wflag: 0진행 1패배 2무승부 3승리 +int board[BOARD_SIZE][BOARD_SIZE]; +int bingo[BOARD_SIZE][BOARD_SIZE]; + +}; +struct Game MyGame ={0,}; + + +//채팅관련 구조체로 묶을변수 +char chat[NAME_SIZE+BUF_SIZE+1]; +char msgQ[5][NAME_SIZE+BUF_SIZE]; + +//main의 매개변수용 char +char name[NAME_SIZE]="[DEFAULT]"; + +int main(int argc, char* argv[]) +{ + int sock; + struct sockaddr_in serv_addr; + pthread_t snd_thread, rcv_thread, gam_thread; + void* thread_return; + + srand(time(NULL)); + int check_number[BOARD_SIZE * BOARD_SIZE] = { 0 }; + for (int i = 0; i < BOARD_SIZE; i++) + { + for (int j = 0; j < BOARD_SIZE; j++) + { + while (1) + { + int temp = rand() % 25; + + if (check_number[temp] == 0) + { + check_number[temp] = 1; + MyGame.board[i][j] = temp + 1; + break; + } + } + } + } + + + + if (argc != 4) { + printf("ip, port, name"); + exit(1); + } + sprintf(name,"[%s]",argv[3]); + + sock = socket(PF_INET, SOCK_STREAM, 0); + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family=AF_INET; + serv_addr.sin_addr.s_addr = inet_addr(argv[1]); + serv_addr.sin_port = htons(atoi(argv[2])); + + if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) + error_handling("connect err"); + pthread_create(&snd_thread, NULL, send_msg, (void*)&sock); + pthread_create(&rcv_thread, NULL, recv_msg, (void*)&sock); + pthread_create(&gam_thread, NULL, game_set, (void*)&sock); + //pthread_detach(snd_thread); + //pthread_detach(rcv_thread); + //pthread_detach(gam_thread); + pthread_join(snd_thread, &thread_return); + pthread_join(rcv_thread, &thread_return); + pthread_join(gam_thread, &thread_return); + if(1){ + close(sock); + return 0;} +} + +void* send_msg(void* arg) { + int sock = *((int*)arg); + char msg[BUF_SIZE]; + sprintf(chat,"%1s%10s","S",name);//이름을 최초 1회 보내는걸로 검증한다. + write(sock, chat, strlen(chat)); + while (1) + { + //배열버퍼, stdin버퍼 초기화 + for(int i=0; i -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BOARD_SIZE 5 -#define BUF_SIZE 100 - -void* send_msg(void* arg); -void* recv_msg(void* arg); - -void error_handling(char* mse); -void game_print(int any); - -int turn_count = 0; -int board[BOARD_SIZE][BOARD_SIZE]; -char* chatting[BUF_SIZE]; -char chat[BUF_SIZE]; -int chattingCount = 0; - - -int main(int argc, char* argv[]) -{ - int sock; - struct sockaddr_in serv_addr; - pthread_t snd_thread, rcv_thread, gam_thread; - void* thread_return; - - srand(time(NULL)); - int check_number[BOARD_SIZE * BOARD_SIZE] = { 0 }; - for (int i = 0; i < BOARD_SIZE; i++) - { - for (int j = 0; j < BOARD_SIZE; j++) - { - while (1) - { - int temp = rand() % 25; - - if (check_number[temp] == 0) - { - check_number[temp] = 1; - board[i][j] = temp + 1; - break; - } - } - } - } - - - - if (argc != 3) { - printf("ip, port"); - exit(1); - } - - sock = socket(PF_INET, SOCK_STREAM, 0); - - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family=AF_INET; - serv_addr.sin_addr.s_addr = inet_addr(argv[1]); - serv_addr.sin_port = htons(atoi(argv[2])); - - if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) - error_handling("connect err"); - - pthread_create(&snd_thread, NULL, send_msg, (void*)&sock); - pthread_create(&rcv_thread, NULL, recv_msg, (void*)&sock); - pthread_join(snd_thread, &thread_return); - pthread_join(rcv_thread, &thread_return); - - close(sock); - return 0; -} - -void* send_msg(void* arg) { - int sock = *((int*)arg); - char msg[BUF_SIZE]; - while (1) { - fgets(msg, BUF_SIZE, stdin); - if (!strcmp(msg, "q\n")||!strcmp(msg,"Q\n")) - { - close(sock); - exit(0); - } - else if(!strcmp(msg, "c\n")||!strcmp(msg,"C\n")) { - sscanf(chat, "%s", msg); - write(sock, chat, strlen(chat)); - } - sprintf(msg, "%s", msg); - write(sock, msg, strlen(msg)); - } - return NULL; -} -void* recv_msg(void* arg) { - int sock = *((int*)arg); - char msg[BUF_SIZE]; - char chat[BUF_SIZE]; - int str_len; - while (1) { - str_len = read(sock, msg, BUF_SIZE - 1); - if (str_len == -1) - return (void*)-1; - msg[str_len] = 0; - - if(atoi(msg) == 0) - { - chatting[chattingCount++] = msg; - } - fputs(msg, stdout); - game_print(0); - } - return NULL; -} - -void error_handling(char* msg) -{ - fputs(msg, stderr); - fputc('\n', stderr); - exit(1); -} - -void game_print(int any) -{ - int i, j, x; - - system("clear"); - printf("%c[1;33m", 27); - - printf("@------ client bingo ------@\n"); - printf("turn: %d\n", turn_count++); - printf("+----+----+----+----+----+\n"); - for (i = 0; i < BOARD_SIZE; i++) - { - for (j = 0; j < BOARD_SIZE; j++) - { - if (board[i][j] == 0) - { - printf("| "); - printf("%c[1;31m", 27); - printf("%2c ", 88); - printf("%c[1;33m", 27); - } - else - printf("| %2d ", board[i][j]); - } - printf("|\n"); - printf("+----+----+----+----+----+\n"); - } - for (x = 0; x < chattingCount; x++) { - printf("%s\n", chatting[x]); - } - printf("%c[0m", 27); - if (turn_count != 0) - { - printf("number: %d\n", 1); - printf("bingo count: %d\n", 1); - } -} \ No newline at end of file diff --git a/s.c b/s.c index d41e2d3..8ff05c5 100644 --- a/s.c +++ b/s.c @@ -10,25 +10,47 @@ #include #include #define BOARD_SIZE 5 +#define NAME_SIZE 10 #define BUF_SIZE 100 #define BACKLOG 3 #define MAX_CLNT 256 void error_handling(char* mse); void* handle_clnt(void* arg); -void send_msg(char* msg, int len); +void* handle_game(void* arg); +void* status_board(void* arg); +void send_msg(char* msg, int len,int index); + -int turn[4]; int clnt_cnt = 0; int clnt_socks[MAX_CLNT]; +int Game_on=0;//게임이 시작되면 1이 되고, 추가 접속을 막는다. 게임이 끝나면 2가 되고, exit한다(쓰레드정리+동적할당정리+main끝) +int win_check =0;//RCV쓰레드와 GM쓰레드가 함 사용하므로 전역변수 + //가장 어려운 세마포를 제어하는 전역변수이다. 클라이언트가 N(숫자)를 입력할때 마다 win_check이 1씩 증가한다. + //하지만 서버쪽에서 실제로는 win_check이 clnt_cnt만큼 증가한다. 클라이언트가 1번 입력하면 AUTO_SendALL을 통해 모든 클라이언트가 그값에 반응을 하기때문이다. + //그러므로 win_check이 clnt_cnt과 같다면 단일 클라이언트가 1번입력한것에 대해 모든 클라이언트가 반응했다는 뜻이다. + //즉 내가 빙고를 완성했을때, 다른 클라이언트도 반응했는지 체크하고, 통신이 원활하게 이루어졌는지 검증할수 있게된다. + +struct Clnt{ + char IP[16]; + int PORT; + char NAME[10];//동적할당으로 수정전에 NAME_SIZE를 10으로 임의 + int R;//0은 준비중 1은 준비완료 2는 게임중 3은 게임중+ + int Bingo;// +}; +struct Clnt C[MAX_CLNT]; //what a massive +char msgQ[5][NAME_SIZE+BUF_SIZE]; //SND쓰레드와 RCV쓰레드가 함께 사용하므로 전역변수 pthread_mutex_t mutx; pthread_t t_id; +pthread_t t_id2; +pthread_t t_id3; int main(int argc, char* argv[]) { int serv_sock, clnt_sock; struct sockaddr_in serv_adr, clnt_adr; int clnt_adr_sz; + char name[NAME_SIZE]="[DEFAULT]"; pthread_t t_id; if (argc != 2) { printf("insert port."); @@ -47,40 +69,140 @@ int main(int argc, char* argv[]) if (listen(serv_sock, 5) == -1) { error_handling("listen() error"); } - printf("var reset, ip port allocate, listen"); - while (1) { + printf("var reset, ip port allocate, listen, setting all cleared. start in 5sec \n"); + sleep(5); + + pthread_create(&t_id2, NULL, status_board, (void*)&clnt_sock); + pthread_detach(t_id2); + + pthread_create(&t_id3, NULL, handle_game, (void*)&clnt_sock); + pthread_detach(t_id3); + + while (Game_on!=1) { + int str_len; + char msg[1+NAME_SIZE+BUF_SIZE]; clnt_adr_sz = sizeof(clnt_adr); clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_adr, &clnt_adr_sz); pthread_mutex_lock(&mutx); - clnt_socks[clnt_cnt++] = clnt_sock; + clnt_socks[clnt_cnt] = clnt_sock; pthread_mutex_unlock(&mutx); pthread_create(&t_id, NULL, handle_clnt, (void*)&clnt_sock); pthread_detach(t_id); - printf("Connected Clnt IP : %s \n", inet_ntoa(clnt_adr.sin_addr)); - - printf("* %s:%d connect\n", inet_ntoa(clnt_adr.sin_addr), ntohs(clnt_adr.sin_port)); - printf(".\n"); + strcpy(C[clnt_cnt].IP,inet_ntoa(clnt_adr.sin_addr));//클라이언트 주소저장 + C[clnt_cnt].PORT=ntohs(clnt_adr.sin_port);//클라이언트의 포트저장 + C[clnt_cnt].R=0;//클라이언트가 레디하지않음으로 설정 + clnt_cnt++; } + if(Game_on!=2){ close(serv_sock); return 0; + } } -void error_handling(char* msg) -{ +void error_handling(char* msg){ fputs(msg, stderr); fputc('\n', stderr); exit(1); } -void* handle_clnt(void* arg) { +void* handle_clnt(void* arg) {//클라이언트를 1대1로 담당하는 쓰레드이자, 수신을 담당하는 쓰레드. 이쓰레드에서 사용되는 변수는 전역변수로 설정할지 검증되어야 한다. int clnt_sock = *((int*)arg); int str_len = 0, i; - char msg[BUF_SIZE]; - + //int win_check=0; //전역변수로 되었음 + char msg[1+NAME_SIZE+BUF_SIZE]; + for(int i=0; i1&&C[0].R==1&&Game_on==0) + { + + int sum=0; + for(int i=0; i1)//무승부 + { + for(int i=0; i