解析字符串并尝试查找“\0”时出错特点
我试图让一侧向客户端发送错误消息,但客户端无法正确解析它。
我的错误是>>>>>在我的 parseString 函数中,它让 index = 0,因此我的“substr”调用超出范围。
服务器端:::
#define ERRBUFSIZE 51
string error = "Error - Already Registered: ";
error.append(name);
char err[ERRBUFSIZE];
err[0] = 0;
std::copy(error.begin(), error.end(), err+1);
err[error.size() + 2] = '\0';
if (send(sock, &err, ERRBUFSIZE, 0) < 0)
{
DieWithError("send() failed");
}
客户端(谁正在接收)::
char msgBuffer[ERRBUFSIZE];
int bytesRcvd = 0;
int totalRcvd = 0;
while(totalRcvd != ERRBUFSIZE)
{
// Get Message from Server
if ((bytesRcvd = recv(sock, msgBuffer, ERRBUFSIZE, 0)) < 0)
DieWithError("recv() failed or connection closed prematurely");
totalRcvd += bytesRcvd;
}
cout << "Bytes received: " << totalRcvd << endl;
msgBuffer[totalRcvd] = '\0';
string rcvMsg( msgBuffer , msgBuffer + totalRcvd);
cout << rcvMsg << endl;
rcvMsg = parseString(rcvMsg);
return rcvMsg;
在哪里....
string TCPClient::parseString(string message)
{
cout << "parsing new string" << endl;
int index = message.find('\0');
string result = message.substr(0, index);
cout << "THE RESULT :: " << result << endl;
return result;
}
I'm trying to get one side to send an error message to client, but client isn't able to parse it correctly.
My error is >>>>> in my parseString function, it lets index = 0 and therefore I get an out of range for my 'substr' call.
Server Side:::
#define ERRBUFSIZE 51
string error = "Error - Already Registered: ";
error.append(name);
char err[ERRBUFSIZE];
err[0] = 0;
std::copy(error.begin(), error.end(), err+1);
err[error.size() + 2] = '\0';
if (send(sock, &err, ERRBUFSIZE, 0) < 0)
{
DieWithError("send() failed");
}
Client side ( who is receiving )::
char msgBuffer[ERRBUFSIZE];
int bytesRcvd = 0;
int totalRcvd = 0;
while(totalRcvd != ERRBUFSIZE)
{
// Get Message from Server
if ((bytesRcvd = recv(sock, msgBuffer, ERRBUFSIZE, 0)) < 0)
DieWithError("recv() failed or connection closed prematurely");
totalRcvd += bytesRcvd;
}
cout << "Bytes received: " << totalRcvd << endl;
msgBuffer[totalRcvd] = '\0';
string rcvMsg( msgBuffer , msgBuffer + totalRcvd);
cout << rcvMsg << endl;
rcvMsg = parseString(rcvMsg);
return rcvMsg;
where....
string TCPClient::parseString(string message)
{
cout << "parsing new string" << endl;
int index = message.find('\0');
string result = message.substr(0, index);
cout << "THE RESULT :: " << result << endl;
return result;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
为什么不将 parseString 更改为以下内容:
然后将调用代码更改为:
如果失败,您甚至可以使用字符串的“size()”函数。
编辑:还值得注意的是, find 将在字符串中前进,直到找到 '\0' 字符,但实际上不会查找它。将字符串放入字符串对象(存储长度),然后尝试通过缓慢的迭代过程自己计算长度,这似乎有点奇怪。
Edit2:如果您只想使用字符数组来执行此操作,您可以按如下方式进行手动搜索。
就这么简单:)
Why not change your parseString to the following:
And then change the calling code to:
Failing that you could even use the string's "size()" function.
Edit: Its also worth noting that find will advance through the string until the '\0' character is found but WON'T actually look for it. It seems a bit of an odd plan to put a string into a string object (Which stores length) and then try and calculate length yourself through a, slow, iterative process.
Edit2: If you just want to do it with a character array you can do a manual search as follows.
Its that simple :)
从(非常难以阅读)代码来看,我认为您可能会遇到“索引地狱”。
检查
totalRecvd
实际上是您想要写入\0
的索引,并且在创建rcvMsg
时添加>\0
对其进行索引(当您将字符串结尾标记放在totalRcvd
字节上时,msgBuffer + TotalRcvd
看起来很糟糕,通常您会得到您编写的 (start, end-1) 索引之间的字符串)。另外 - 搜索
\0
没有任何意义,因为它只是一个标记。另外 (2) - 如果
totalRcvd == ERRBUFSIZE
您无法访问msgBuffer [totalRcvd]
,您只能访问范围(0, ERRBUFSIZE -1)
From the (very-difficult-to-read-)code, I think you might be running into "indexing hell".
Check that
totalRecvd
actually is the index where you want to write that\0
and that when you create yourrcvMsg
you're adding the\0
index to it (msgBuffer + totalRcvd
looks dogdy when you've put your end-of-string marker on thetotalRcvd
byte, usually you get a string between (start, end-1) indexes you write).Also - searching for the
\0
makes no sense as that is just a marker.Also (2) - if
totalRcvd == ERRBUFSIZE
you can't accessmsgBuffer [totalRcvd]
, you only have access to the indexes in range(0, ERRBUFSIZE -1)
当您想要管理缓冲区时,请使用 std::vector 而不是 std::string。 '\0' 和 std::basic_string 结合得不好。
Use std::vector instead of std::string when you want to manage buffers. '\0' and std::basic_string doesn't combine well.
首先,协议很糟糕。当您想要发送以 null 结尾的字符串时,您正在发送固定大小的块...将字符串长度放在消息的前面会更简单。
其次,您没有从套接字正确读取数据,只要管道中没有任何其他消息,它就会正常工作。
如果您的 while 循环曾经真正被执行过,您将用任何后续读取覆盖第一个片段。
无论如何,该错误的直接原因是您在字符串前面添加了一个 nul 终止符(分隔符?)。这难道不能解释为什么你总是在索引 0 处找到 nul 吗?
如果看不到它,请尝试写出发送时缓冲区的内容。
First, the protocol is nasty. You're sending fixed-size blocks when you want to send a nul-terminated string ... it would be simpler just to put the string length at the front of the message.
Second, you're not reading correctly from the socket, it just happens to work so long as you don't have any other messages in the pipeline.
If your while loop was ever really exercised, you'd overwrite the first fragment with any subsequent reads.
Anyway, the proximate cause of the bug is that you prepend a nul terminator (separator?) to the string. Doesn't that explain why you always find your nul at index 0?
If you can't see it, try writing out the contents of the buffer as sent.