我需要从服务器接收消息,到目前为止我可以做到这一点,但我仍然有一个问题,我不知道它是什么。该文本定义消息采用以下格式:
我试图接收该消息,所以我使用了接收函数,它位于
之下/**
Receive data from the connected host
*/
string client::receive(int size){
//string buffer;
string reply;
std::vector<char> buffer(size, 0);
//strcpy(buffer, "\0");
// memset(&buffer[0], 0, sizeof(buffer));
int result = recv(sock, buffer.data(), buffer.size(), 0);
if( result < 0){
puts("recv failed");
}
cout << "read bytes: " << result << endl;
cout << "buffer: " << buffer.data() << endl;
//reply = stringToBit(buffer);
reply = buffer.data();
cout << "reply: " << reply << endl;
return reply;
}
但问题是,当我暂时接收接收以接收所有消息时,事情开始变得奇怪。起初,我意识到我只需要清理缓冲区,但事情仍然很奇怪,因为对于消息,我收到的信息是:
第一条消息: NULL - 收到的字节数:2
第二条消息:用户接受 - 接收的字节数:14
第3条消息:5 - 接收的字节数:1
第4条消息: NULL - 收到的字节数:2
第5条消息: unprintable_char 501&amp; xt,md-ldt ='t&lt; 1t?1-t $; =: - 收到的字节数:30
第6条消息: NULL - 收到的字节数:1
第5条消息总是会改变,但其余的消息(消息和字节数)总是相同的。当从3中查看消息1时,我认为可能有3个是大小的标题,2是消息,3是校验和。但是,接收所有那些 NULL 而不是任何有用的信息,否则会让我感到厌烦。
有人对可能发生的事情有所了解吗?我对服务器没有控制权,我只能相信服务器按照规定发送这些消息。
答案 0 :(得分:1)
服务器会向您发送邮件大小。你必须利用这个优势。此外,定义您的功能的方式使报告错误变得困难。你应该考虑这样的事情:
// receives a fixed number of bytes. returns zero or a negative number on error
int client::receiveBytes(size_t n, void* buffer)
{
char* p = reinterpret_cast<char*>(buffer);
while (n)
{
int got = recv(sock, p, n, 0);
if (got <= 0)
return got;
n -= got;
p += got;
}
return 1;
}
/**
Receive data from the connected host
*/
int client::receive(std::string& reply)
{
reply.clear();
uint16_t replyLength = 0; // or the appropriate 16-bit type if your compiler doesn't provide <cstdint>
int result = receiveBytes(2, &replyLength);
if (result <= 0)
return result;
if (replyLength == 0) // <-- you could add more length validation here
return -1; // <-- or whatever error code you wish...
reply.resize(replyLength);
result = receiveBytes(replyLength, &reply[0]);
if (result <= 0)
return result;
// verify the checksum. failure indicates we have lost sync...
// I'm assuming here that the checksum is computed using plain char's,
const char* p = reinterpret_cast<const char*>(&replyLength);
char chksum = *(p++) + *p;
for (size_t i = 0; i < replyLength - 1; ++i)
chksum += reply[i];
if (chksum != reply[replyLength - 1])
{
// there is not much that can be done to recover sync with this protocol
// the best option the caller has is to close the connection and start anew.
reply.clear();
return -1; // or whatever error code you wish...
}
reply.resize(replyLength - 1);
return reply.size();
}
答案 1 :(得分:-1)
我为16位整数创建了另一个接收函数(由于某种原因我不知道),我意识到字节已被交换。例如:
我收到号码3840,二进制表示法是:0000111100000000
但我应该收到15,二进制表示是: 0000000000001111
所以,除了接收之外,我还添加了一些字节交换的想法
int client::receiveSize(){
int16_t size;
int result = recv(sock, &size, sizeof(size), 0);
int hibyte = (size & 0xff00) >> 8;
int lobyte = (size & 0xff);
size = lobyte << 8 | hibyte;
cout << "received: " << size << " and " << result<< endl;
return size;
}
我意识到了(方式!我学到了一些东西),我应该准确地说明我将在recv上接收的数据类型。否则,我可以获得没有意义的信息。