Почему эта последовательность функций отправки / получения приводит к непредсказуемому поведению получения / строки? - PullRequest
0 голосов
/ 22 марта 2012

Я пытаюсь отправлять и получать строки от клиента к серверу другому клиенту, и я получаю некоторые неожиданные результаты.На стороне клиента я читаю в таких строках.Он сканирует вводимые пользователем данные и затем отправляет их на сервер следующим образом.Затем он ждет, пока сервер отправит обратно имя другого клиента.

int getHandle() {
 int numbytes;
 char temp[11];
 temp[0] = 'H'; temp[1] = '\0';
 printf("Please enter in a handle (name) of length 10\n");
 fflush(stdout);
 fgets(handle, sizeof(handle), stdin);
 handle[strlen(handle) - 1] = '\0';
 strcat(temp, handle);
 int len = strlen(temp);
 sendall(master_sock, temp, &len);
 printf("Waiting for other player to connect....\n");
 bzero(buf2, sizeof(bu2));
 //We will wait until we get the opponents name
 if ((numbytes = recv(master_sock, buf2, sizeof(buf2), 0) == -1)) {
      perror("receive");
      exit(1);
 }
 printf("Receiving name from player 2 of: %s\n", buf2);
 if (buf2[0] == 'H') {
      int i;
      for ( i = 1; i < 12; i++) {
           if (buf2[i] == '\0' || buf2[i] == '\n' || buf2[i] == '\r') {
                handle2[i -1] = '\0';
           } else {
                handle2[i -1] = buf2[i];
           }
      }
 }

 printf("Opponents handle is %s. \n", handle2);
 bzero(buf2, 52);

Когда сервер считает, что у него есть два имени, он отправляет их обратно, используя следующую функцию:

void sendhandles() {
 int len1 = strlen(player1);
 int len2 = strlen(player2);

 printf("Player 1 handle = %s, Player 2 handle = %s\n", player1, player2);
 if (sendall(player1_fd, player1, &len1) == -1) {
      error("sendall");
      fprintf(stderr, "Only sent %d bytes \n", len1);
 }   
 if (sendall(player2_fd, player2, &len2) == -1) {
      error("sendall");
      fprintf(stderr, "Only sent %d bytes \n", len2);
 }   

 //Might as well ask for their initial configs
 char getcfg[] = "GG";
 int cfg = strlen(getcfg);
 if (sendall(player1_fd, getcfg, &cfg) == -1) {
      error("sendall");
      fprintf(stderr, "Only sent %d bytes \n", len1);
 }   
 if (sendall(player2_fd, getcfg, &cfg) == -1) {
      error("sendall");
      fprintf(stderr, "Only sent %d bytes \n", len1);
 }   
}

И клиент, и сервер используют одну и ту же функцию отправки (адаптированоиз руководства Биджа здесь )

int sendall(int s, char *bufx, int *len) {
 printf("Sending .%s. to %d.\n", bufx, s);
int total = 0; //bytes sent      
int remainder = *len; //bytes left
int n; 

while(total < *len) {
    n = send(s, bufx+total, remainder, 0);
    if (n == -1) { break; }
    total += n; remainder -= n; 
}  

*len = total; // return number actually sent here
if (n == -1) {
 fprintf(stderr, "Didn't send it all\n");
}  
return n==-1?-1:0; // return -1 on failure, 0 on success
}

Проблема в том, что иногда он не отправляет обратно правильные имена.То есть он отправит обратно как имя, так и затем "GG".Сервер сообщает, что "GG" отправляется отдельно оба раза, но по какой-то причине клиент считает, что имя и "GG" находятся в одном буфере.Пример вывода выглядит следующим образом:

Please enter in a handle (name) of length 10
FDSA
Sending .HFDSA. to 3.
Waiting for other player to connect....
Receiving handle from player 2 of: HFDSAGG
Opponents handle is FDSAGG. 

Сервер сообщает об этом:

 Sending .HASDF. to 4.
 Sending .HFDSA. to 5.
 Sending .GG. to 4.
 Sending .GG. to 5.

Таким образом, похоже, что сервер отправляет информацию правильно, но где-то на стороне клиента, этосмешивает его в одном буфере.Я не уверен почему, так как я обнуляю это каждый раз.Странно то, что иногда это работает, но иногда нет.Кажется, он не различает, с какого клиента я запускаюсь первым.Любые предложения будут высоко оценены!

...