为什么这个发送/接收函数序列导致不可预测的接收/字符串行为?

时间:2012-03-22 02:45:36

标签: c sockets send recv

我正在尝试从客户端向服务器发送和接收字符串到另一个客户端,我得到了一些意想不到的结果。在客户端,我读了这样的字符串。它扫描用户输入,然后将其发送到服务器。然后它等待服务器发回另一个客户端的名称。

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);
 }   
}

客户端和服务器都使用相同的发送功能(改编自Beej的指南here

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.

所以看起来服务器正在正确地发送信息,但是在客户端的某个地方,它在同一个缓冲区中将它们混合在一起。我不知道为什么,因为我每次都把它归零。奇怪的是,它有时会起作用,但有时却不起作用。它似乎没有歧视我首先启动的客户端。任何sugestions将非常感谢!

0 个答案:

没有答案