[英]Error with parsing string and trying to find '\0' character
我試圖讓一方將錯誤消息發送給客戶端,但是客戶端無法正確解析它。
我的錯誤是我的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;
}
為什么不將您的parseString更改為以下內容:
string TCPClient::parseString(const string& message, int strLength )
{
cout << "parsing new string" << endl;
string result = message.substr( 0, strLength );
cout << "THE RESULT :: " << result << endl;
return result;
}
然后將調用代碼更改為:
rcvMsg = parseString(rcvMsg, totalRcvd );
否則,您甚至可以使用字符串的“ size()”函數。
編輯:還值得注意的是,查找將通過字符串前進,直到找到'\\ 0'字符,但實際上不會查找它。 將字符串放入字符串對象(存儲長度),然后嘗試通過一個緩慢的迭代過程自己計算長度,這似乎有些奇怪。
Edit2:如果只想使用字符數組,則可以執行以下手動搜索。
int index = 0;
while( *charString++ != '\0' ) index++;
就這么簡單:)
從(非常難於閱讀)代碼來看,我認為您可能會遇到“索引地獄”的問題。
檢查totalRecvd
實際上是您要寫入\\0
的索引,並在創建rcvMsg
時向其中添加\\0
索引(當您放置字符串結束標記時, msgBuffer + totalRcvd
看起來像狗狗一樣在totalRcvd
字節上,通常會在您寫入的(start,end-1)個索引之間得到一個字符串)。
另外-搜索\\0
沒有任何意義,因為那只是一個標記。
另外(2)-如果totalRcvd == ERRBUFSIZE
您無法訪問msgBuffer [totalRcvd]
,則只能訪問范圍為(0, ERRBUFSIZE -1)
的索引
要管理緩沖區時,請使用std :: vector而不是std :: string。 '\\ 0'和std :: basic_string結合不好。
首先,該協議令人討厭。 當您要發送一個以nul結尾的字符串時,您將發送固定大小的塊...將字符串長度放在消息的開頭會更簡單。
其次,您沒有從套接字正確讀取數據,只要管道中沒有其他消息,它就可以正常工作。 如果您的while循環曾經真正行使過,則您將用隨后的所有讀取覆蓋第一個片段。
無論如何,該錯誤的直接原因是您在字符串前添加了nul終止符(分隔符?)。 難道不是在解釋為什么總是在索引0處找到nul嗎? 如果看不到,請嘗試寫出發送時緩沖區的內容。
#define ERRBUFSIZE 51
void server(string const &name)
{
string error = "Error - Already Registered: ";
error.append(name);
char err[ERRBUFSIZE];
// you sure you want a NUL terminator at index 0??
err[0] = 0;
// can replace both lines with strcpy(err, error.c_str())
std::copy(error.begin(), error.end(), err+1);
err[error.size() + 2] = '\0';
if (send(sock, &err, ERRBUFSIZE, 0) < 0)
DieWithError("send() failed");
}
string parseString(string const &message) // no need to copy
{
// ... this is redundant anyway, see below
}
string client()
{
char msgBuffer[ERRBUFSIZE];
int bytesRcvd = 0;
int totalRcvd = 0;
while(totalRcvd != ERRBUFSIZE)
{
// Get Message from Server
// ... recv(sock, msgBuffer+totalRcvd, ERRBUFSIZE-totalRcvd) ...
if ((bytesRcvd = recv(sock, msgBuffer, ERRBUFSIZE, 0)) < 0)
DieWithError("recv() failed or connection closed prematurely");
totalRcvd += bytesRcvd;
}
cout << "Bytes received: " << totalRcvd << endl;
//sizeof(msgBuffer)==ERRBUFSIZE==totalRcvd, so this overflows
msgBuffer[totalRcvd] = '\0';
// assuming you skip the leading \0, msgBuffer is already nul-terminated
// so use string rcvMsg(msgBuffer) and skip the parseString/substr
string rcvMsg( msgBuffer , msgBuffer + totalRcvd);
cout << rcvMsg << endl;
// rcvMsg = parseString(rcvMsg);
return rcvMsg;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.