// 검은색 : 서버.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 |