2014-12-04 2 views
0

다음은 클라이언트를 수락하는 코드입니다 ... 이제 방금 list<Client> 인 풀에 추가 할 비트를 추가했습니다. Client(SOCKET, Char*) 소켓 및 IP 주소로 정의되는 클래스입니다. addclient2pool() 함수는 목록에 추가하기 만합니다. 그런 다음 목록을 반복하고 Client에 저장된 소켓을 통해 데이터를 보냅니다.C++ 사용자 지정 클라이언트 처리기

while(true) { 
    ClientSocket = accept(ListenSocket, (struct sockaddr *) &n, &len); 
    if (ClientSocket == INVALID_SOCKET) { 
     printf("accept failed with error: %d\n", WSAGetLastError()); 
     closesocket(ListenSocket); 
     WSACleanup(); 
     return; 
    } 
    addClient2Pool(Client(ListenSocket, inet_ntoa(n.sin_addr))); 
} 

소켓 그래서 난 ... 10057 메시지를 전송할 수없는 폐쇄 것으로 보인다. Client 클래스에 소켓을 저장하는 방식에 근본적으로 잘못된 점이 있지만 C++을 처음 접했습니다.

void messageHandler() { 
    int iSend; 
    char* charB = "hello!"; 
    while(true) { 
     for(ClientPool::iterator it = mainClientPool.begin(); it != mainClientPool.end(); ++it) { 
      Client c = *it; 
      SOCKET sock = c.getSocket(); 
      iSend = send(sock, charB, sizeof(charB),0); 
      if (iSend == SOCKET_ERROR) { 
       printf("send failed with error: %d\n", WSAGetLastError()); 
      } 
     } 
     Sleep(2000); 
    } 
} 

나는 std::thread nameofthread(void) 내가 코드와 몇 가지 문제를 참조

답변

0

nameofthread.join();을 사용했다. 당신이 어떤 이유로 서버를 종료해야하는 경우, 먼저 활성 클라이언트 소켓을 닫아야합니다

addClient2Pool(Client(ClientSocket, inet_ntoa(n.sin_addr))); 

: 대신 ClientSocket를 전달해야 할 때

당신은 Client()ListenSocket을 전달하고 있습니다. accept()이 실패 할 경우의 예에서, 먼저 mainClientPool을 지우지 않고 closesocket(ListenSocket)WSACleanup()을 요구하고있다 (나는 당신의 ~Client() deconstructor 클라이언트 소켓에 closesocket()를 호출 가정) :

mainClientPool.clear(); // <-- add this 
closesocket(ListenSocket); 
WSACleanup(); 

목록을 통해 반복, 당신은을 사용할 필요가 당신은 그들이 범위에서 갈 때 소멸자를 호출하여 Client 객체의 임시 복사본을 만드는되지 않도록 반복자를 deferencing 때 Client& 참조 (따라서 클라이언트 소켓을 닫는) :

Client &c = *it; // <-- add '&' 

sizeof()을 오용하고 있습니다. charBchar* 아닌 char[] 때문에, 대신 strlen()를 사용해야합니다 : send() (또는 다른 소켓 작업)이 실패 할 때

iSend = send(sock, charB, strlen(charB), 0); 

마지막을, 당신은 실패한 클라이언트 소켓을 닫고 목록에서 제거해야합니다 . 즉 for() 루프를 while() 루프로 변경하면 루프를 반복하면서 목록을 수정할 수 있습니다.

void messageHandler() { 
    ... 
    while(true) { 
     ... 
     ClientPool::iterator it = mainClientPool.begin(); 
     while (it != mainClientPool.end()) { 
      ... 
      if (iSend == SOCKET_ERROR) { 
       ... 
       it = mainClientPool.erase(it); 
      } else { 
       ++it; 
      } 
     } 
     ... 
    } 
    ... 
} 
관련 문제