2011-12-18 4 views
2

UDP 소켓을 사용하는 C로 간단한 카운트 다운 응용 프로그램을 구현하려고합니다. 응용 프로그램의 서버 부분에 매우 이상한 문제가 있습니다. 클라이언트에서 숫자를 받고 카운트 다운에 다른 숫자를 보내야합니다. 예를 들어, 사용자가 클라이언트에 5를 입력하면 서버는 5를 받고 4, 3, 2, 1 및 0을 클라이언트에 보내야합니다.간단한 클라이언트/서버 카운트 다운 C 응용 프로그램의 이상한 동작

#define BUFFERSIZE 512 
#define PORT 55123 

void ClearWinSock() 
{ 
    #if defined WIN32 
     WSACleanup(); 
    #endif 
} 

int main() 
{ 
    #if defined WIN32 

    WSADATA wsaData; 
    WORD wVersionRequested; 

    wVersionRequested = MAKEWORD(2, 2); 

    if(WSAStartup(wVersionRequested, &wsaData) != 0) 
    { 
     printf("Error: unable to initialize the socket!\n"); 
     return -1; 
    } 

    #endif 

    int mainSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 

    if(mainSocket < 0) 
    { 
     printf("Error: unable to create the socket!\n"); 
     ClearWinSock(); 
     return -1; 
    } 

    struct sockaddr_in serverSockAddrIn; 
    memset(&serverSockAddrIn, 0, sizeof(serverSockAddrIn)); 
    serverSockAddrIn.sin_family = AF_INET; 
    serverSockAddrIn.sin_port = htons(PORT); 
    serverSockAddrIn.sin_addr.s_addr = inet_addr("127.0.0.1"); 

    if(bind(mainSocket, (struct sockaddr*) &serverSockAddrIn, sizeof(serverSockAddrIn)) < 0) 
    { 
     fprintf(stderr, "Error: unable to bind the socket!\n"); 
     ClearWinSock(); 
     return -1; 
    } 

    char buffer[BUFFERSIZE]; 

    struct sockaddr_in clientAddress; 
    unsigned int clientAddressLength; 
    int recvMessageSize; 

    while(1) 
    { 
     clientAddressLength = sizeof(clientAddress); 

     recvMessageSize = recvfrom(mainSocket, buffer, BUFFERSIZE, 0, (struct sockaddr*) &clientAddress, &clientAddressLength); 

     int countdownValue; 

     sscanf(buffer, "%d", &countdownValue); 

     printf("\nNumber received: %d\n", countdownValue); 

     int index; 

     for(index = countdownValue - 1; index >= 0; --index) 
     { 
      itoa(index, buffer, 10); 

      int outputStringLength = strlen(buffer); 

      if(sendto(mainSocket, buffer, outputStringLength, 0, (struct sockaddr*) &clientAddress, sizeof(clientAddress)) != outputStringLength) 
      { 
       printf("Error: unable to send the message!"); 
      } 
     } 
    } 

    ClearWinSock(); 
    return 0; 
} 

이제 문제는 내가, 예를 들어, 클라이언트에서 숫자 5를 보내는 경우, 때때로 서버가 제대로 작동하고 때로는 "번호 수신 : 5"를 말한다 : 전송하지 않습니다 여기 내 코드입니다 그리고 나서 "Number received : 0"이 5 번 나타납니다.

소켓을 사용하는 데 문제가 있다고 생각합니다. 아니면 버퍼를 청소하는 것과 관련된 것일 수도 있습니다. 동일한 입력으로 때때로 어떤 방식 으로든 다른 방식 으로든 작동하기 때문에 오류를 재현 할 수 없습니다.

+0

아무것도 :

또는, 당신은 항상 바인드()를 호출하기 전에 다음 코드를 실행하여 동일한 포트를 공유하는 클라이언트와 서버에 지시 할 수 있습니다? 나는 recvfrom하기 전에 버퍼를 청소하려고했으나 변경되지 않았습니다. – JohnQ

+0

이제 오류를 복제하는 방법을 알았습니다. 서버 전에 클라이언트를 시작하면 응용 프로그램이 작동하지 않습니다. 내가 서버를 시작한 다음 클라이언트를 시작하면 모두 괜찮습니다. 어쩌면 소켓 초기화가있는 것일까 요? – JohnQ

답변

0

클라이언트와 서버 모두 동일한 포트에서 수신 대기합니까? 그렇다면 서로 다른 포트에서 수신 대기 (예 : 클라이언트가 X로 전송하고 포트 Y에서 수신 대기, 서버가 포트 Y로 전송 및 수신 대기)하여 서로 간섭하지 않거나 실수로 수신하지 못하게 할 수 있습니다 클라이언트와 서버가 동일한 호스트에서 실행될 때 자신이 전송 한 패킷.

const int trueValue = 1; 
    setsockopt(mainSocket, SOL_SOCKET, SO_REUSEADDR, (const char *) &trueValue, sizeof(trueValue)); 
관련 문제