2013-09-23 3 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

Смежные вопросы