앞서 만든 Echo 멀티 쓰레드 코드에 약간의 변형을 주어 채팅 서버로 변환할 수 있다.
- 클라이언트 TCP 세션을 관리하는 개별 쓰레드가 클라이언트 수 만큼 존재한다.
- 연결된 모든 클라이언트를 관리하기 위한 자료구조가 필요하다.
- 쓰레드에서 자료구조에 삭제, 추가, 접근 해야하기 때문에 쓰레드 동기화 작업이 필요하다.
서버에 접속하는 유저를 리스트로 관리한다.
// 새로 연결된 클라의 소켓을 리스트에 저장한다.
BOOL AddUser(SOCKET hSocket)
{
// CriticalSection을 이용해 동기화를 시작한다.
::EnterCriticalSection(&g_cs); // 임계영역 시작
g_listClient.push_back(hSocket);
::LeaveCriticalSection(&g_cs); // 임계영역 끝
return TRUE;
}
CriticalSection을 이용해 동기화를 시작하면 쓰레드가 진입해 LeaveCriticalSection을 호출하기 전까지
다른 쓰레드는 g_listClient에 socket을 저장할 수 없다.
이처럼 다른 쓰레드의 임계영역이 끝나야만 다른 쓰레드가 작업할 수 있으므로 임계구간은 최소화하는것이 좋다.
연결된 클라들에게 메세지를 전송한다.
void SendChattingMessage(char *pszParam)
{
int nLength = strlen(pszParam);
std::list<SOCKET>::iterator it;
::EnterCriticalSection(&g_cs); // 임계영역 시작
for(it = g_listClient.begin(); it != g_listClient.end(); ++it)
{
::send(*it, pszParam, sizeof(char)* (nLength + 1), 0);
}
::LeaveCriticalSection(&g_cs); // 임계영역 끝
}
멀티쓰레드 기반 채팅 클라이언트 7분 강의
'네트워크' 카테고리의 다른 글
[네트워크] 우아하지 않은 비정상 종료 (0) | 2025.04.14 |
---|---|
[네트워크] 멀티 쓰레드 채팅 클라이언트 (0) | 2025.04.14 |
[네트워크] 멀티 쓰레드 Echo (0) | 2025.04.11 |
[네트워크] 소켓에서 버퍼링을 하는 이유 (0) | 2025.04.10 |
[네트워크] Nagle's Algorithm ( 네이글 알고리즘 ) (0) | 2025.04.09 |