2013-09-23 150 views
-2

這是一個多客戶端套接字程序。recvfrom包含多餘字節

當我試圖運行我的程序時,最後幾個recvfrom()不返回任何數據。但是之前的收益有過剩的數據。有人可以幫助我如何解決這個問題。

客戶:

while (1) { 
memset(buff, 0, sizeof(buff)); 
recvfrom(sockfd,buff,sizeof(buff),0,(struct sockaddr *)&servaddr,&len); 
printf("%s\n", buff); 
if (buff[0] == 'U') { 
    while(1) { 
     printf("Insert your username: "); 
     fgets(username,sizeof(username),stdin); 
     username[strlen(username) - 1] = '\0'; 
     printf("Username chosen is %s\n", username); 
     // Username Check (Error Check) 
     if (strlen(username) < 1 || strlen(username) > 16) { 
      printf("Minimum of 1 and maximum of 16.\n"); 
      continue; 
     } 
     for (i = 0; i < strlen(username); i++) { 
      if (isalnum(username[i]) == 0) { 
       printf("Username must contain only alphanumeric characters.\n"); 
       j = 0; 
       break; 
      } 
     } 
     if (j = 0) { 
      continue; 
     } else { 
      break; 
     }  
     } 
     sendto(sockfd,username,strlen(username),0,(const struct sockaddr *)&servaddr,len); 

     memset(username, 0, sizeof(username)); 

    } else { 
     break; 
    } 
}    

printf("Players:\n"); 

memset(buff, 0, sizeof(buff)); 

for (i = 0; i < numplayer; i++) { 
    printf("BUFF: %s\n", buff); 
    recvfrom(sockfd,buff,sizeof(buff),0,(struct sockaddr *)&servaddr,&len); 
    printf("%s\n", buff); 

    memset(buff, 0, sizeof(buff)); 


}  

服務器:

 for (i = 0; i < numplayer; i++) { 
    while (1) { 
     memset(mesg,0,sizeof(mesg)); 
     if (recvfrom(connfd[i],mesg,sizeof(mesg),0,(struct sockaddr *)&cliaddr,&len) < 0) { 
      perror("Recvfrom"); 
      exit(-1); 
     } 
     for (j = 0; j < numplayer; j++) { 
      if (strcmp(username[j], mesg) == 0) { 
       // Reinitialize buff 
       memset(buff, 0, sizeof(buff)); 
       check = 1;   
       break; 
      } 
     } 

     if (check == 1) { 
      check = 0; 
      sprintf(buff, "Username already exist!"); 
      if (sendto(connfd[i],buff,strlen(buff),0,(const struct sockaddr *)&cliaddr,len) < 0) { 
       perror("Sendto"); 
       exit(-1); 
      } 
      memset(buff, 0, sizeof(buff)); 

      continue; 
     } else { 
      sprintf(buff, "Valid Username!"); 
      if (sendto(connfd[i],buff,strlen(buff),0,(const struct sockaddr *)&cliaddr,len) < 0) { 
       perror("Sendto"); 
       exit(-1); 
      } 
      strcpy(username[i], mesg); 
      printf("Username of Player %d is %s.\n" ,i + 1,username[i]); 
      break; 
     } 
    } 
} 
    printf("Players:"); 
for (i = 0; i < numplayer; i++) { 
    memset(buff, 0, sizeof(buff)); 

    sprintf(buff, "> %s", username[i]); 
    printf("%s\n", buff); 

    for (j = 0; j < numplayer; j++) { 
     if (sendto(connfd[j],buff,strlen(buff),0,(const struct sockaddr *)&cliaddr,len) < 0) { 
      perror("Sendto"); 
      exit(-1); 
     } 
    } 
} 
+0

你似乎沒有任何理解recvfrom如何工作。閱讀文檔並查找示例。另外,看看EJP說什麼。 – xaxxon

回答

1

有沒有 '多餘字節'。 recvfrom()返回一個長度。你忽略了它。它也可能是EOS(0)或錯誤指示(-1,請參閱'errno')。你需要檢查所有這些可能性。

0

TCP連接可能會將您發送的數據分段爲較小的數據包。

如果您正在接收已知大小的數據,接收器必須使用循環來獲取有效負載的所有字節。

如果您是網絡編程新手,您可以找一些圖書館爲您完成這項工作。

Boost's asio是我能想到的,但其語法可能有點困難。

+0

或更大。它可能會合並。 – EJP

+0

哈,是的,沒錯。謝謝。 TCP非常棘手。 – leesei

+0

我如何才能停止接收字節,如果我想接收的只是sendto的一次使用發送的字節? – Red