我正在创建一个程序,可以获取包并通过C++将其打印到控制台.我将char数组设置为1024,如:
char* buffer = new char[1024];
Run Code Online (Sandbox Code Playgroud)
当我收到一条消息不完全是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();
Run Code Online (Sandbox Code Playgroud)
服务器由C++控制台应用程序编写
char* recvData = new char[1024];
recv(socket, recvData, strlen(recvData), 0);
cout << recvData << endl;
Run Code Online (Sandbox Code Playgroud)
代码有三个问题:
recvData传递给时是单元化的strlen().strlen()当找到空终止字符(可能在缓冲区内或外部)时,确定缓冲区的长度.缓冲区的大小(小于终止空字符的大小)应作为要读取的最大字节数传递.recv()是没有被查询.代码将使用recvData即使recv()失败,这是一个错误.recv() 不为null终止缓冲区.保存结果,recv()如果不-1将其用作索引recvData,则插入空终止字符.
或者,因为这是c ++使用a 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;
}
Run Code Online (Sandbox Code Playgroud)
请记住,通过套接字发送的数据只是一个字节流,它不会分成不同的消息.这意味着:
out.write("I am your client :D");
Run Code Online (Sandbox Code Playgroud)
可能无法通过一次调用来读取recv().相等:
out.write("I am your client :D");
out.write("OK");
Run Code Online (Sandbox Code Playgroud)
可能只需一次调用即可阅读recv().如果需要基于消息的处理,程序员有责任实施协议.
strlen计算'\0'遇到null()字符之前的字节数.无法保证单个recv调用返回的数据将被终止,因此您需要检查返回的字节数,然后添加自己的终结符.
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;
}
Run Code Online (Sandbox Code Playgroud)