카테고리 없음

채팅프로그램 이론

twoweeks-within 2024. 11. 8. 18:39

프로토콜 ( 통신 규약) : 통신할때 하나하나 의미들, 약속
ex) 랜선 ( 랜선도 약속: 8개 선으로 a로는 뭘하고 b로는 뭘하고,,)

 

1. TCP 통신
a가 b로 패킷 하나 날림 > 그걸 잘 받았는지 또 패킷 > 확인 받는 절차 : 복잡, 안전성 있음 (ex) 파일 다운
<->
2. UDP 통신
패킷 빠르게 날리기만함 > 확인 절차 없음 (ex) 게임, 실시간 스트리밍
3. 소켓 ex) 충전 타입(c ,8 , 5핀) ,돼지코, 220v 
> 이런것도 다 통신 규약
여러가지 hw 들이 하나의 구멍(충전기 꼽는 그 두개 구멍)으로 통신 할 수 있도록 해주는것

소켓단 2가지
1. 서버 : 서비스 제공 
 : 소켓을 열고 리슨 하고 있는 상태
2. 클라이언트 : 서비스를 받아감
: 소켓을 열고 ip 서버주소 로 connect를 시도하는 객체

리틀엔디안 빅엔디안
50000 이라는 숫자를 받을때
1 2 3 4 순으로 할지 (빅)
4 3 2 1 순으로 할지 (리틀)
> 운영체제마다 저장 방식이 다름
>> 다른 체제를 만나면 다른 숫자로 받아들여짐>> 의미전달 x
>>> 통일규약: 네트워크 > 네트워크오더를 사용 ( 빅엔디안 )
 
sockaddr_in 기본 구조체
struct sockaddr_in {
    short sin_family;      // 주소 패밀리 (예: AF_INET)
    unsigned short sin_port; // 포트 번호 (네트워크 바이트 순서)
    struct in_addr sin_addr; // IP 주소
    char sin_zero[8];      // 여분의 공간 (사용하지 않음)
};
// 헤더파일 #include <netinet/in.h> 

 

bind 함수

ex) bind(serv_sock,(struct sockaddr *)&serv_addr,sizeof(serv_addr));

serv_sock 라는 소켓과 serv_addr 의 구조체를 bind

> sockaddr 타입의 포인터를 기대함

>> (struct sockaddr *)&serv_addr:  serv_addr의 주소를 sockaddr 포인터로 변환

디테일한 옵션들
SO_REUSEADDR : 소켓을 닫으면 원래 운영체제가 포트를 놔줄때까지 기다려야하는데,

                                 포트번호를 즉시 재사용 할 수 있게 해주는 옵션 
TCP_NODELLAY :  위에서 말한 하나를 보내더라도 바로바로 보내라는 옵션

채팅프로그램 뼈대
구성) 서버, 유저 1,2,3
유저 1 > 서버 > 유저 2,3,
유저2 > 서버 > 유저 1,3
>> 한 유저가 말하면 서버 접속한 사람 다 볼 수 있음

서버 :
  유저1 > accept- u1(받는 쓰레드) > u1과 주고받음 
  유저2 >  "   - u2 (read only) > u2 와 주고받음
                "   - all (send) > 유저에게 뿌려주는        
클라이언트 : 
유저 keybord입력 > send(보내는 쓰레드)
서버로부터의 all > read (받는 쓰레드)

운영체제: 이것도 하나의 큰 프로그램 - 여러 프로그램,쓰레드 등을 관리함
> 운영체제 역할을 할 수 있게 코드가 짜여있을뿐

임베디드 에서.. 부팅
0x00 : cpu명령어 > 부트코드
>HDD,F/M : 코드(main함수) > while(1){}문 돎
> 컴파일러 코드를 만나면 컴파일러 프로그램 할 수 있게 해줌
> 결국 운영체제도,,컴파일러도,, 읽기 전에는 코드 덩어리일뿐

프로세스
운영체제가 디스크 내의 코드> 메모리 에 올려놓음
>스케쥴러(a,b,c를 스케쥴따라 우선순위대로 올려놓음) 
>>process

하나의 프로세스는 메인 함수 하나만 돌릴 수 있음
> 내부에 쓰레드(임시공간) 을 여러개
>멀티태스킹,context changing 으로 여러개 실행
(요새는 cpu도 멀티코어라 1쓰레드에 1 cpu 하기도함)
 

멀티태스킹: 운영체제가 프로세스 1,2,3,, 빠른 속도로 왔다갔다하면서
 > 동시에 하는것처럼 보임

context changing : 멀티태스킹 할때 1번 하던걸 저장하고 2번하던거 하다가
                                 1번 하던걸로 다시돌아오는 것

 

다른 프로세스 예: 그림판, 계산기 ,,등등 크롬 등등

기본적인 운영체제 작동
p1(프로세스1) , p2 ,, 있을때
서로의 변수에 접근 하지 못하도록 되어있음
> 공유메모리로 가능하기는 함 + 인젝션(별도의 프로그램이 중간에 간섭) // inject :주입하다
but,, 
1프로세스안에 쓰레드 들을 사용하면
변수들을 내부에서 메모리 공유하며 변수,함수같은걸 가지고 놀 수 있음 

 

mutex
ex) 쓰레드1에서 a를 2번 쓰려고 하는데
if) 순서가 쓰레드1 ( a++) > 쓰레드2 (a--) > 쓰레드1 순으로 처리가 되어버리면 ,, //운영체제 맘대로

기대 : a++ > a++

결과: a++ > a-- > a++  
> 다른 값 > 크리티컬 영역

t1 a: lock > if) t2:접근 > 대기 시킴 > t1 a2: unlock > t2 실행
but,,, t1 a lock 이 갑자기 죽으면 t2 a : 데드락 발생 (프로그램 응답없음) 

ex)

thread77 : a[1]
thread77 : a[2] //  a[1] 을 가져옴
thread88 : a[2] // a[1]  을 가져옴 // 원래 기다렸다가 a[2]를 가져와야함
thread88 : a[3]
>mutex를 안하면 a[2] 에서  77과 88이 동시에 ++a를 해버리는 경우가 생길 수 있음

 

쓰레드는 메모리를 사용한다
> 메모리 반환을 잘 해줘야한다


 -lpthread : pthread 라는 라이브러리를 참조해라 ( libpthread.so)
없는 경우에는 ,, libpthread.so 를 직접 크로스컴파일로 만들어줘야함  

 

형변환 주의
int id1 = 77 
(void *)id1 = 0x4d ( 77) 
>  77 이라는 주소로 인식함  > 컴파일오류

(void *) &id1 = id1의 주소번지

*(int *)&id1 = 77


join 
원래 : main 이 끝나면 프로그램이 끝나버림
> join
쓰레드가 다 끝날때까지 기다려줌