2011-12-18 13 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

これでエラーを再現する方法を知っています。サーバーの前でクライアントを起動するとアプリケーションが動作しません。私がサーバを起動してからクライアントを起動すると、すべてOKです。たぶんソケット初期化の何かですか? – JohnQ

答えて

0

クライアントとサーバーの両方が同じポートで待機していますか?そうであれば、クライアントが異なるポートでリッスンすることを考慮する(クライアントがXに送信してポートYを待ち受け、サーバーがポートYに送信してポートXをリッスンするなど)、相互に干渉したり誤って受信したりすることはないクライアントとサーバーの両方が同じホスト上で実行されているときは、送信済みのパケットを送信します。

const int trueValue = 1; 
    setsockopt(mainSocket, SOL_SOCKET, SO_REUSEADDR, (const char *) &trueValue, sizeof(trueValue)); 
関連する問題