앞서 만든 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분 강의

+ Recent posts