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