如何在c ++中在套接字上写多行

时间:2017-03-24 00:24:29

标签: c++ sockets

套接字编程很新,只是有一个简短的问题,我试图在服务器上显示我的客户端上的多行输出,但我似乎无法将这些行分开。任何帮助表示赞赏。

服务器:

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

1 个答案:

答案 0 :(得分:1)

您的代码有三个问题:

  1. 您对write()的调用包括字符串的空终止符。在这种情况下你不应该那样。

  2. 您的read()代码忽略了read()的返回值。仅仅因为你要求255个字节并不能保证你会收到255个字节。返回值告诉您实际接收的字节数。并且您确实收到的字节也不能保证为空终止,因此您不能将缓冲区仅作为char*指针写入std::cout,这将使其找到空终止符。 std::cout有一个write()方法,您可以使用该方法指定要写入的char个。{1}}。为此目的使用read()的返回值。

  3. 除此之外,您假设对read()的调用将读取一个完整的行,以便您可以检查最后一个接收缓冲区中char的{​​{1}}最终的L行。这根本不是真的,你不能依赖它。 TCP是一个字节流,LEAVE将接收并返回任意数量的数据,具体取决于套接字接收缓冲区中的可用内容。如果需要读取基于行的数据,则必须将输入字节累积到某种增长的缓冲区中,然后在新数据到达时扫描该字符串以进行换行。然后,您只能从该缓冲区中删除已完成的行,并根据需要处理其内容。

  4. 尝试更像这样的东西:

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