본문 바로가기
일상,취미

다시 시작하는 TIL 22일차

by 진득한진드기 2024. 7. 6.

오늘 한일 

 

오늘 최근에 일한일 중에 제일 바쁘게 일한 것 같다.

 

먼저 자료구조 지원안하는거에서 좀 시간을 많이 버렸다.

 

학부 시절 자료구조 시간에 구현했던 해시테이블이랑 연결 리스트를 구현할 줄은 몰랐다.

 

근데 문제는 학부시절 때보다 내가 현재 상황에 맞춰서 구현하는거라 좀 엉거주춤하면서 전진해 나가는 느낌으로 구현한 것 같다.

 

일단 오늘 본것 중 가장 큰일났다고 생각한건 윈도우 프로그래밍에서 특정 오브젝트가 계속 생기는데 생기는 오브젝트에 대해 관리해주지 못했다.

 

알고보니 내가 코드를 짤 때 

 

특정 언어 x

Thread *thread_manage = Thread.Create();

 

이런식으로 이벤트가 일어나거나 오브젝트가 생성되면 변수하나로만 관리하고 있었다.

 

뭐 오브젝트가 무조건 한개만 생성하는 것도 아닌데 이런식으로 코딩하면 같은 이벤트가 여러번 일어날 때 

 

저 thread_manage변수는 레퍼런스 카운팅이 풀렸다가 재할당 되기 때문에 이전에 가르키던 쓰레드의 변수들이 다 날아간다.

 

즉 메모리 관리가 아예 안되는 것 변수이름은 관리자인데 관리가 하나도 안되고 있었다.

 

그래서 List도 직접 구현해서 Object가 생성되면 List에 추가해줬다.

 

Thread *thread_manage = Thread.Create();
ListAdd(thread_manage);

 

요런식으로...... 뭐 List 삽입도 그랬고 오브젝트가 순서대로 사라지는게 아니기에 오브젝트가 사라질때 이벤트가 일어나 사라지는 자기의 주소를 알려준다. -> 이를 List에서 탐색해서 해당 오브젝트를 Free하는 방식으로 해결했다.

 

근데 당장 프론트에서도 이 모양인데 저 코드를 보듯 엔진에서도 저렇게 짰을거 같다는 무서운 마음이 들어 확인해봤더니

 

엔진에서도 저렇게 짜놨다.

 

진짜 정신 나갔나보다. 바로 엔진 Thread들도 List로 관리되게 수정했다. 근데 진짜 말이 쉽지 쓰레드들이 전부다 자기구조화 되어있어서 조건에 맞게 삭제되게 구현한게 생각보다 어려웠다.

 

그래도 뭔가 혼자일 할 때 이렇게 해치워서 다행이다.

 

퇴근 후 공부

 


Time-Wait의 이해

 

서버, 클라이언트에 상관없이 TCP 소켓에서 연결의 종료를 목적으로 Four-way handshaking의 첫 번째 메시지를 전달하는 호스트의 소켓은 Time-wait 상태를 거친다.

 

 Time-wait 상태 동안에는 해당 소켓이 소멸되지 않아서 할당 받은 Port를 다른 소켓이 할당할 수 없다.

 

Time-wait의 존재이유 


호스트 A의 마지막 ACK가 소멸되는 상황을 대비해서 Time-wait 상태가 필요하다.
호스트A의 마지막 ACK가 소멸되면 ,호스트 B는 계속해서 FIN메시지를 호스트 A에 전달하게 된다.



그림과 같이 마지막 ACK를 보내고 상대 소켓은 바로 소멸되지만 A의 소켓은 Time-wait로 들어간다.

그래서 저 time-wait 상태일 때는 사용중이었던 port는 운영체제가 해당 소켓을 가지고 있기때문에 사용이 불가능해진다.


만약 Time-wait가 없을 때


마지막에 보낸 ACK메시지가 사라졌다고 해보자.

상대는 마지막 ACK를 못받았기 때문에 FIN 메시지를 못받은줄 알고 FIN메시지를 보낸다. 

 

근데 ACK를 보내고 소켓을 닫아버리면 닫아버린 사람은 FIN을 받을 수가 없기 때문에 
상대는 답답한 상황이 올수가 있다. 

 

상대는 닫은걸 모르니 계속 FIN을 보내게 된다. 이렇게 상대가 ACK 못받아서 답답해 하지 않게 하는게 time-wait다.

즉 Time-Wait는 상대를 위해서 존재하는 것.

 


Time-wait은 길어질 수 있다.


Time-wait은 필요하다. 그러나 실 서비스중인 서버의 경우 Time-wait가 문제가 될 수 있다. 그러한 경우 TIME-WAIT상태에 있는 port의 할당 가능하도록 코드르 수정해야한다.

4 handshaking 마지막 ACK에 일어나는 것이므로, 상대가 ACK을 못받았으면 다시 FIN을 보낸다. 그래서 FIN을 받으면 time-wait 상태를 다시 재가동해야한다. 

하지만 서비스중에는 종료되었다고 해서 time-wait 상태가 몇분 걸리는데 이 때 그 사이 몇분사이에 무슨일이 일어날지 모른다.

이럴땐 time-wait상태를 무시하고 소켓을 닫아야한다.

이럴땐 Port 할당이 가능하도록 옵션의 변경이 가능해야한다.

optlen = sizeof(option);
option = TRUE;
setsockopt(serv_sock, SOL_SOCKET, SO_REUSERADDR,  (void P)&option, optlen);





 

 

'일상,취미' 카테고리의 다른 글

다시 시작하는 TIL 24일차  (0) 2024.07.10
다시 시작하는 TIL 23일차  (0) 2024.07.08
다시 시작하는 TIL 21일차  (0) 2024.07.05
다시 시작하는 TIL 20일차  (0) 2024.07.04
다시 시작하는 TIL 19일차  (1) 2024.07.03