繁体   English   中英

关于C ++中的socket recv和char []

[英]About socket recv and char[] in C++

我正在创建一个程序,该程序可以获取程序包并将其通过C ++打印到控制台。 我将char数组设置为1024,例如:

char* buffer = new char[1024];

当我收到一条不完全是1024个字符的消息时,由于数组中的空白,消息末尾有许多未知字符。 我能做什么?

更多信息(我不知道它是否有用)

套接字是由Java程序发送的

Socket socket = new Socket("127.0.0.1", 27555);

BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
out.write("I am your client :D");
out.flush(); 

服务器由C ++控制台应用程序编写

char* recvData = new char[1024];
recv(socket, recvData, strlen(recvData), 0);
cout << recvData << endl;

该代码存在三个问题:

  • recvData传递给strlen()时会统一。 当找到空终止符时, strlen()确定缓冲区的长度,该终止符可以在缓冲区之内或之外。 缓冲区的大小(小于等于终止空字符的大小)应作为要读取的最大字节数传递。
  • 不查询recv()的结果。 即使recv()失败,代码也将使用recvData ,这是一个错误。
  • recv()不能为null终止缓冲区。

保存recv()的结果,如果不为-1 ,则将其用作recvData的索引以插入空终止符。

另外,因为这是c ++,所以请使用std::vector<char>并为您管理动态内存分配(如果确实需要动态内存分配):

std::vector<char> recvData(1025); // Default initializes all elements to 0.
int result = recv(socket, recvData.data(), recvData.size() - 1);
if (result != -1)
{
    std::cout << recvData.data() << std::endl;
}

请记住,通过套接字发送的数据只是字节流,不会分成不同的消息。 这意味着:

out.write("I am your client :D");

一次调用recv() 可能无法读取它。 相等:

out.write("I am your client :D");
out.write("OK");

可以通过一次调用recv()来读取。 如果需要基于消息的处理,则程序员有责任实施协议。

strlen计算字节数,直到遇到null( '\\0' )字符为止。 不能保证单个recv调用返回的数据将被n终止,因此您需要检查返回的字节数,然后添加自己的终止符。

char* recvData = new char[1024];
int bytes = recv(socket, recvData, 1023, 0);
if (bytes == -1) {
    cout << "error on recv" << endl;
}
else {
    recvData[bytes] = '\0';    
    cout << recvData << endl;
}

recvData不是以null结尾的 ,因此在这种情况下strlen()结果是不确定的。 您必须执行以下操作:

int len = 1024;
char *recvData = new char[len + 1];
int lenRead = recv(socket, recvData, len, 0);
if (lenRead < len)
    recvData[lenRead] = '\0';
else
    recvData[len] = '\0'; 
cout << recvData << endl;

这不是很明显吗? :)

只需先发送字符串的长度或“正确”终止字符串(通过在字符串末尾发送\\0 ;我想这是Java在这里没有做的事情)。

但是总的来说,无论如何,您都应该包括“数据包长度”,因为您可能要确保在写入缓冲区之前有足够的可用空间strlen()在未初始化的数组上使用strlen()通常是个坏主意)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM