套接字编程很新,只是有一个简短的问题,我试图在服务器上显示我的客户端上的多行输出,但我似乎无法将这些行分开。任何帮助表示赞赏。
服务器:
void help(int sock)
{
n = write(sock,"Commands:\n",11);
n = write(sock,"HELP -> Displays usable commands\n",34);
n = write(sock,"BROADCAST 'message' -> Sends 'message' to every user\n",54);
n = write(sock,"SEND 'user' 'message' -> Sends 'message' to 'user'\n",52);
n = write(sock,"DISPLAY -> Displays all current users\n",39);
n = write(sock,"LEAVE -> Ends the current session\n",35);
}
客户端:
while(buffer[0] != 'L')
{
bzero(buffer,256);
n = read(sockfd,buffer,255);
cout << buffer << "\n";
}
答案 0 :(得分:1)
您的代码有三个问题:
您对write()
的调用包括字符串的空终止符。在这种情况下你不应该那样。
您的read()
代码忽略了read()
的返回值。仅仅因为你要求255个字节并不能保证你会收到255个字节。返回值告诉您实际接收的字节数。并且您确实收到的字节也不能保证为空终止,因此您不能将缓冲区仅作为char*
指针写入std::cout
,这将使其找到空终止符。 std::cout
有一个write()
方法,您可以使用该方法指定要写入的char
个。{1}}。为此目的使用read()
的返回值。
除此之外,您假设对read()
的调用将读取一个完整的行,以便您可以检查最后一个接收缓冲区中char
的{{1}}最终的L
行。这根本不是真的,你不能依赖它。 TCP是一个字节流,LEAVE
将接收并返回任意数量的数据,具体取决于套接字接收缓冲区中的可用内容。如果需要读取基于行的数据,则必须将输入字节累积到某种增长的缓冲区中,然后在新数据到达时扫描该字符串以进行换行。然后,您只能从该缓冲区中删除已完成的行,并根据需要处理其内容。
尝试更像这样的东西:
read()
int writestr(int sock, const char *str)
{
int n, len = strlen(str);
while (len > 0)
{
n = write(sock, str, len);
if (n < 0) return n;
str += n;
len -= n;
}
return 0;
}
void help(int sock)
{
n = writestr(sock, "Commands:\n");
n = writestr(sock, "HELP -> Displays usable commands\n");
n = writestr(sock, "BROADCAST 'message' -> Sends 'message' to every user\n");
n = writestr(sock, "SEND 'user' 'message' -> Sends 'message' to 'user'\n");
n = writestr(sock, "DISPLAY -> Displays all current users\n");
n = writestr(sock, "LEAVE -> Ends the current session\n");
}