C언어

[c] 채팅프로그램

twoweeks-within 2024. 11. 7. 19:22

// 검은색 : 서버.c , 파란색 : 클라.c

1. 서버측 서버소켓 (한개) // 지금은 비어있음

2. 소켓 구조체 : ip, port, 주소,,

3. bind : 소켓 에 구조체를 넣음

4. listen // 사람들 오기를 기다림

A. 클라측 소켓 // 비어있음

B. 소켓 구조체 // 서버와 동일 IP, 주소,port // 127.0.0.1 로컬 

C. connect 

  C-1) 클라측 소켓 에 구조체 넣음

  C-2) listen() 하고 있는 파일과 연

5. accept () > 서버측 클라소켓에저장

  5-1) 서버측클라소켓 > 전체용 소켓(a) (전역)

  5-2) 서버측클라소켓 > 쓰레드공간(b)

6. (b) read: 소켓으로 오는 메세지를 읽음 > 출력

7. (a) 로 메세지와 현재 소켓을 넘김 (함수)

D. 소켓을 쓰레드에도 연

E. write : fgets로 입력해서 , 소켓을 통해 msg를 넣음

8. (a) write : 들어온 소켓을 통해 msg 출력

F. 8에서 wite 된것을 read

 

//소켓이  accept 까지 되면 read write를 할 수 있음

// 사실 메세지가 아니라 버퍼를 보내는것임

// 소켓이라는 통로에 버퍼라는 메모리를 보내는것

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <arpa/inet.h>

#define CLNT_MAX 10
#define BUFFSIZE 1024

int g_clnt_socks[CLNT_MAX];
int g_clnt_count = 0;

pthread_mutex_t g_mutex;

void send_all_clnt(char * msg,int my_sock){

                pthread_mutex_lock(&g_mutex);
        for(int i=0; i< g_clnt_count ; i++){
                if(g_clnt_socks[i] != my_sock){
                        write(g_clnt_socks[i],msg,strlen(msg)+1);
                }
        }

                pthread_mutex_unlock(&g_mutex);
}

void * clnt_connection(void * argv){
        int clnt_sock = *(int*)argv;
        char msg[BUFFSIZE];

        while(1){
                read(clnt_sock,msg,sizeof(msg));
                printf("%s\n",msg);

                send_all_clnt(msg,clnt_sock);

        }

        pthread_mutex_lock(&g_mutex);

        for(int i=0;i<g_clnt_count ; i++){
                if(clnt_sock == g_clnt_socks[i]){
                        for(;i<clnt_count-1;i++){
                                g_clnt_socks[i]= g_clnt_socks[i+1];
                        }
                }
        }
        close(clnt_sock);
        pthread_mutex_unlock(&g_mutex);
        return NULL;
}
int main(int argc,char** argv){
        int serv_sock;
        struct sockaddr_in serv_addr;
        pthread_mutex_init(&g_mutex,NULL);

        serv_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=htonl(INADDR_ANY);
        serv_addr.sin_port=htons(7989);
        bind(serv_sock,(struct sockaddr *)&serv_addr,sizeof(serv_addr));

        listen(serv_sock,5);

        while(1){
                struct sockaddr_in clnt_addr;
                int clnt_sock;
                int clnt_sock_size;
                clnt_sock_size=sizeof(clnt_sock);
                clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_sock_size);
                pthread_mutex_lock(&g_mutex);
                g_clnt_socks[g_clnt_count++] = clnt_sock;
                pthread_mutex_unlock(&g_mutex);
                pthread_t t_thread;
                pthread_create(&t_thread,NULL,clnt_connection,(void*)&clnt_sock);
        }
        close(serv_sock);
        return 0;
}

서버.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>

#define BUFFSIZE 1024

void * rcv(void * arg){
        int sock = *(int*)arg;

        char buff[BUFFSIZE];
        while(1){
                read(sock,buff,sizeof(buff));
                printf("%s",buff);

        }
        pthread_exit(0);
        return 0;
}
int main(int argc, char **argv){

        int sock;
        sock= socket(PF_INET,SOCK_STREAM,0);
        struct sockaddr_in serv_addr;

        pthread_t rcv_thread;

        memset(&serv_addr,0,sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        serv_addr.sin_port = htons(7989);

        connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr));

        char id[100];
        strcpy(id,argv[1]);
        printf("ID:%s\n",id);
        pthread_create(&rcv_thread,NULL,rcv,(void *)&sock);
        char chat[100];
        while(1){
                printf("MESSAGE: ");
                fgets(chat,sizeof(chat),stdin);
                sprintf(msg,"[%s] : %s",id,chat);
                printf("SEND : %s ",msg);

                write(sock, msg, strlen(msg)+1);
                }          
        close(sock);
        return 0;
}

클라이언트.c

'C언어' 카테고리의 다른 글

정리 - 2 -  (0) 2024.11.11
각종 정리 -1  (2) 2024.11.08
makefile (script language)  (1) 2024.11.07
[c] 헤더파일, 문자열입력  (0) 2024.11.07