2011-12-18 48 views
2

我想在C中使用UDP套接字實現一個簡單的倒計時應用程序。 我對應用程序的服務器部分有一個很奇怪的問題:它應該從客戶端接收一個數字,然後發送不同的倒數數字。因此,例如,如果用戶在客戶端鍵入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」,不發任何事情,然後它說5次「收到號碼:0」。

我想我在使用套接字時出錯了。或者,也許這是涉及清理緩衝區的東西,不知道!我無法重現錯誤,因爲在輸入相同的情況下,它有時會以某種方式行動,有時會以另一種方式行事。

+0

什麼?我試圖在recvfrom之前清理緩衝區,但它不會改變東西... – JohnQ

+0

好吧,現在我知道如何複製錯誤:如果我在服務器啓動客戶端之前我的應用程序不起作用。如果我啓動服務器,然後客戶端就沒事了。也許這是與套接字初始化? – JohnQ

回答

0

您的客戶端和服務器都在同一端口上偵聽嗎?如果是這樣,你可能需要考慮讓它們監聽不同的端口(例如,客戶端發送到X並監聽端口Y;服務器發送到端口Y並監聽端口X),以便它們不會相互干擾或意外接收當客戶端和服務器都在同一主機上運行時,它們會自己發送數據包。

或者,您也可以指導客戶端和服務器通過調用bind()之前,請務必執行以下代碼共享相同的端口:

const int trueValue = 1; 
    setsockopt(mainSocket, SOL_SOCKET, SO_REUSEADDR, (const char *) &trueValue, sizeof(trueValue)); 
相關問題