2014-03-01 2 views
0

클라이언트가 서버에 로그인을 요청하고 다른 클라이언트의 온라인 상태를 보도록 요청할 수있는 서버/클라이언트 통신 시스템을 프로그래밍하고 있습니다. 클라이언트 로그를 정상적으로 만들 수 있지만 (성공적으로) 로그인 한 다음 다른 클라이언트의 정보를 요청하는 다른 패킷을 보내면 서버가 해당 패킷을받지 못합니다.패킷을 지속적으로 보내고받는 방법은 무엇입니까?

서버의 주요 부분이 아닌 기술적 인 연결 물건 바인드 서버 시작 :

Users client[2]; //I intialized them already 

//Bind 
bind(WelcomeSocket, (sockaddr*)&SvrAddr, sizeof(SvrAddr)); 

//listening 
listen(WelcomeSocket, 5); 

//temp users 
Users temp; 

//while loop for the connection 
while (1) { 

    ConnectionSocket = accept(WelcomeSocket, NULL, NULL); 



    if (recv(ConnectionSocket, RxBuffer, sizeof(RxBuffer), 0)) 
     cout << "WORKEDDDDDDDD" << endl; 

    memcpy(&temp, RxBuffer, sizeof(struct Users)); 

    cout << temp.message << temp.userName << endl << endl; 

    //check which message type is being sent 
    switch(temp.message) { 

    //if message type 1 
    case 1 : 
     for (int i = 0; i < 2; i++) { 

      //if receieved username matches with any username in the database 
      if (strcmp(temp.userName, client[i].userName) == 0) { 

       //assign the recieved users information to the matched one in database 
       strcpy(client[i].userName, temp.userName); 
       client[i].online = true; 
       client[i].message = 2; 

       cout << client[i].userName << endl << client[i].online << endl; 

       //send the acknowledgement packet 
       send(ConnectionSocket, (char *)&client[i], sizeof(struct Users), 0); 
      } 

     } 
     closesocket(ConnectionSocket); 
     break; 

    //if message type 3 
    case 3 : 
     cout << "3"; 
     break; 

    default : 
     break; 

    } 

} 

closesocket(ConnectionSocket); 
WSACleanup(); 
} 

클라이언트 : 사용자

struct Users { 

int message; 
char userName[50]; 
char ipAddress[50]; 
int PortNumber; 
bool online; 

}; 
에 대한

connect(ClientSocket, (sockaddr*)&SvrAddr, sizeof(SvrAddr)); 



//cout << "Name: "; 
//cin >> login; 

//Send request to login 
int log; 
char * name = new char[128]; 
char * request = new char[128]; 
Users client; 
Users talkto; 



    cout << "To login press (1). "; 
    cin >> log; 
    flushall(); 

    if (log == 1) { 

     cout << "Username : "; 
     cin.getline(name, 128, '\n'); 
     flushall(); 

     //Set client login info 
     strcpy(client.userName, name); 
     client.message = 1; 



     send(ClientSocket, (char *)&client, sizeof(struct Users), 0); 


     //Recieve acknowledgement 
     recv(ClientSocket, RxBuffer, sizeof(RxBuffer), 0); 
     //create temp users 
     Users temp; 

     memcpy(&temp, RxBuffer, sizeof(struct Users)); 



     if (temp.message == 2) { 

      cout << "Enter user for user information: "; 
      cin.getline(talkto.userName, 128, '\n'); 
      flushall(); 
      talkto.message = 3; 

      //send request for user information packet 
      if (send(ClientSocket, (char *)&talkto, sizeof(struct Users), 0)) 
      cout << "SENDT" << endl; 
     } 

     //cout << temp.userName << endl << temp.online << endl << temp.message; 

     closesocket(ClientSocket); 


WSACleanup(); 

}

구조

한 번 이상 정보를받지 못하는 이유를 잘 모름

+0

케이스 1의 스위치에서 소켓을 닫으므로 메시지 유형 1을 수신 한 후 소켓의 연결이 끊어집니다. –

+0

소켓을 닫지 않아도 여전히 같은 문제가 발생합니다 @DavidOtano – user2981393

+0

이유를 알고 있습니다. 'accept' 함수는 다음 클라이언트를 기다리는 나머지 루프를 막고 있습니다. –

답변

0
ConnectionSocket = accept(WelcomeSocket, NULL, NULL); 

당신은이 아닌 내부 루프 전에 넣어해야합니다. 당신의 recv 호출이 0을 반환 할 때 또한

은, 그것은 연결이 닫힌 것을 의미한다, 당신이 당신의 루프에서 중단한다 그래서, 스트림의 마지막 때 recv 0을 반환, 또는 예상치 못한 SOCKET_ERROR.

+0

예, 단일 연결을 제공하는 데 도움이됩니다. 그러나 다른 클라이언트는 연결이 열려있는 동안 연결할 수 없습니다. – Inspired

+0

@ Infpired Indeed. –

+0

놀라운! 나는 if (n == 0) 휴식을 취했다; 내 고객 측에서 조금 고칠 수 있었고 효과가있었습니다! 감사! – user2981393

0

각 클라이언트 연결에 대해 서버는 accept-recv-send-closesocket을 수행합니다. 기간.

서버가 첫 번째 패킷을 처리 한 후 클라이언트에 대한 연결이 닫힙니다. 클라이언트 측에서 각 패킷을 보내기 전에 새 연결을 설정하거나 (즉, 로그인 절차를 쓸모 없게 만들거나) 서버가 여러 개의 동시 클라이언트 연결을 무한 루프에서 폴링하는 것을 유지할 수있게하려면 별도의 스레드에서 수행해야합니다 (에스). accept 기능, 다른 클라이언트를 기다리는 다른 패킷을 수신에서 당신을 차단하기 때문에

+0

서버 측의 while (1) 루프에서 accept-recv-send-closesocket을 사용할 수 있지만 하나 이상의 패킷을 수신 할 수있는 것이 누락 되었습니까? – user2981393

+0

'accept '는 패킷이 아니라 연결을 허용합니다. – Inspired

+0

패킷을 승인하는 것은 recv입니다. 내 서버에서 recv는 패킷을 두 번받지 못한다. 첫 번째 이유를 모르면 멈춘다. – user2981393

관련 문제