简体   繁体   English

从套接字接收时出错

[英]Error on receiving from socket

I need to receive messages from a server and I can do that so far but I still have a problem that I don't know what it is. 我需要从服务器接收消息,到目前为止,我可以做到这一点,但仍然有一个我不知道它是什么的问题。 The text defines that the message is follows format: 文本定义消息遵循以下格式:

  • as header, 2 bytes for the size of the rest of the message (payload + checksum); 作为报头,其余两个消息的大小(有效载荷+校验和)为2个字节;
  • as trailer, 1 byte for checksum (the checksum is calculated including the 2 bytes of the size ) 作为尾部,校验和为1个字节(校验和的计算包括大小的2个字节)
  • , and the rest of bytes are for the payload itself (in the middle of the message) ,其余字节用于有效负载本身(在消息中间)

I was trying to receive that message and so I used a receive function that it's below 我试图接收该消息,所以我使用了下面的接收函数

/**
    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;
    }

but the problem is, when I put the receive in a while to receive all messages, things start to get odd. 但是问题是,当我把接收消息放一会儿来接收所有消息时,事情开始变得奇怪。 At first, I realised that I only needed to clean the buffer but things stay strange because, for the messages, the information I receive are: 最初,我意识到我只需要清理缓冲区,但是事情仍然很奇怪,因为对于消息,我收到的信息是:

1rst Message: NULL - Number of bytes received: 2 1RST消息:NULL -字节数接收的:2

2nd Message: User accepted - Number of bytes received: 14 第二条消息:用户接受-接收的字节数:14

3rd Message: 5 - Number of bytes received: 1 第三条消息:5-接收的字节数:1

4th Message: NULL - Number of bytes received: 2 第4条消息: NULL-接收的字节数:2

5th Message: unprintable_char 501&xt,md-ldt='t <1t?1-t$;=: - Number of bytes received: 30 第五消息:unprintable_char 501&XT,MD-LDT ='吨<1吨1吨$; =: -接收到的字节数:30

6th Message: NULL - Number of bytes received: 1 第6条消息: NULL-接收的字节数:1

.

.

.

The 5th message always change but the rest (messages and number of bytes) are always the same. 第5条消息始终更改,但其余消息(消息和字节数)始终相同。 When looking at messages 1 from 3, I thought that maybe 3 was the header with the size, 2 was the message and 3 the checksum. 当查看3中的消息1时,我认为可能3是带有大小的标头,2是消息,3是校验和。 But, receiving all those NULL instead of any usefull information, makes me thing otherwise. 但是,接收所有这些NULL而不是任何有用的信息会使我感到反感。

Does someone has some idea of what might be happening? 有人对可能发生的事情有所了解吗? I have zero control to the server, I can only believe that the server sends those messages as stated. 我对服务器的控制为零,我只能相信服务器按规定发送了这些消息。

The server sends you the size of the message. 服务器向您发送消息的大小。 You have to use this to your advantage. 您必须利用此优势。 Also, the way you function is defined makes it difficult to report errors. 另外,您定义功能的方式也很难报告错误。 You should consider something like this: 您应该考虑这样的事情:

// 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();
}

I created another receive function just for the 16 bits integers and (for some reason I don't know), I realised that the bytes were exchanged. 我仅为16位整数创建了另一个接收函数,并且(由于某种原因,我不知道)我意识到字节已交换。 For example: 例如:

I received the number 3840, that the binary representation is: 0000111100000000 我收到数字3840,该二进制表示为:0000111100000000

But I was supposed to receive 15, that the binary representation is: 0000000000001111 但是我应该收到15,该二进制表示为:0000000000001111

So, in addition to the receive, I add some byte exchange idea 因此,除了接收之外,我还添加了一些字节交换的想法

 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;
}

I realised (way! I learned something), that I should put exactly the data type that I'll be receiving on the recv. 我意识到(方法!我学到了一些东西),我应该把我将要接收的数据类型准确地放在recv上。 Otherwise, I can get information that doesn't make sense. 否则,我会得到没有意义的信息。

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

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