【问题标题】:send and read string between threads在线程之间发送和读取字符串
【发布时间】:2011-11-20 05:51:27
【问题描述】:

这一直让我很生气,原因是我缺乏 c/c++ 经验。

我不知道如何从另一个线程中读取字符串。在这种情况下,线程来自连接到服务器线程的客户端。我已经能够毫无问题地传递整数。但是似乎无法弄清楚如何传递字符串。

从控制台读取字符串并需要发送到服务器的客户端:

cout << "Enter in an operation and number: \n ";
int x;
char str[20];
int len = strlen(str);
int result;


cin>>str;
cin>>x;

write(client_sock, &len, sizeof(int));
write(client_sock, str, len);
write(client_sock, &x, sizeof(x));

read(client_sock, &result, sizeof(result));
cout<<result;

需要读取字符串的服务器端,为了进行测试,我正在尝试将其发送回来,但是我需要将其读取并将其与其他条件进行比较以对读取的数字执行操作。

int result;
int input;
int len;
char str;

read(client_sock, &input, sizeof(input));
read(client_sock,&len,sizeof(len));
char buf[sizeof(len)];
sscanf(buf, "%s", &str);

cout<<str;
result= input*input;

write(client_sock,&result,sizeof(result));
write(client_sock, buf, strlen(buf));

当然这是一项任务,我的教授告诉我将字符读入缓冲区并以空值终止它。我不确定他的 null 终止是什么意思。我是否也正确地读入了缓冲区?

【问题讨论】:

    标签: c++ string sockets buffer


    【解决方案1】:

    这里有一些提示

    在写作和阅读时都需要执行相同的步骤

    例如首先在套接字上写入字符串的长度(字节数),我想在你的情况下一个字节应该足以描述长度,然后将字符串写入一系列字节。如果您想要更大的字符串,请使用定义明确的数据类型而不是int,例如使用您自己的类型并记住,如果您在平台之间进行通信,您可能需要考虑endianness

    到目前为止,您在写作方面的表现似乎还不错(我猜您忽略了套接字的打开/绑定等):

    write(client_sock, &len, sizeof(unsigned char));
    write(client_sock, str, len);
    

    在接收端,您首先读取长度,然后读取后续字节数:

    read(client_sock, &len, sizeof(unsigned char));
    char* buffer = new char[len + 1]; // create a buffer
    read(client_sock, buffer, len);
    buffer[len]='\0'; // terminate the string
    

    现在你得到了缓冲区中的字符串,只需将其转换为 std::string。

    std::string s = buffer;
    delete [] buffer; 
    

    [免责声明:代码不完整或可编译只是为了说明原则]

    这些是不正确的陈述:

    char buf[sizeof(len)];
    sscanf(buf, "%s", &str);
    

    buf 未初始化且太小,因为 sizeof(len) 将仅返回 int 的大小,并且您实际上是从未初始化的缓冲区读取到具有一个字节空间的字符串中。这里不需要 sscanf。

    【讨论】:

      【解决方案2】:

      以null结尾的字符串是标准的c字符串...一系列字符,后跟一个空字节

      作为一个普通的 ascii 字符串 "Hello" 看起来像

      0x48 (H)
      0x65 (e)
      0x6c (l)
      0x6c (l)
      0x6f (o)
      0x00(空)

      如您所见,您需要一个字符串长度 + 1 字节(空终止符)的缓冲区

      【讨论】:

      • 谢谢,但这对我几乎没有帮助.. 我是否将缓冲区大小设置为 buf[sizeof(len)+1] ... len 是读取的字符串的大小
      【解决方案3】:

      几个cmets:

      cout << "Enter in an operation and number: \n ";
      int x;
      char str[20];
      int len = strlen(str);
      int result;
      

      我不了解 C++,但 C 不会自动为您将内存归零。您的char str[20] ; int len = strlen(str);随机 内存上运行strlen(3)。它可能包含一个字符串。它可能包含来自先前调用堆栈的函数指针。它肯定包含垃圾,并且在其上调用strlen() 也会产生垃圾——甚至可能是分段违规。

      char str;
      /* ... */
      char buf[sizeof(len)];
      sscanf(buf, "%s", &str);
      

      同样,您已经分配了一个字符缓冲区并立即将其未初始化地交给sscanf(3)sscanf(3) 将读取垃圾,它所做的任何事情都不可能是正确的。

      此外,您正在尝试将 字符串 存储到单个字节 (char str) 中。您需要 (a) 将 char str 更改为 char *str (b) 实际上为其分配一些内存。但也许strdup(3) 函数会更有用,因为这看起来你只是想复制字符串。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多