簡體   English   中英

從套接字接收時出錯

[英]Error on receiving from socket

我需要從服務器接收消息,到目前為止,我可以做到這一點,但仍然有一個我不知道它是什么的問題。 文本定義消息遵循以下格式:

  • 作為報頭,其余兩個消息的大小(有效載荷+校驗和)為2個字節;
  • 作為尾部,校驗和為1個字節(校驗和的計算包括大小的2個字節)
  • ,其余字節用於有效負載本身(在消息中間)

我試圖接收該消息,所以我使用了下面的接收函數

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

但是問題是,當我把接收消息放一會兒來接收所有消息時,事情開始變得奇怪。 最初,我意識到我只需要清理緩沖區,但是事情仍然很奇怪,因為對於消息,我收到的信息是:

1RST消息:NULL -字節數接收的:2

第二條消息:用戶接受-接收的字節數:14

第三條消息:5-接收的字節數:1

第4條消息: NULL-接收的字節數:2

第五消息:unprintable_char 501&XT,MD-LDT ='噸<1噸1噸$; =: -接收到的字節數:30

第6條消息: NULL-接收的字節數:1

第5條消息始終更改,但其余消息(消息和字節數)始終相同。 當查看3中的消息1時,我認為可能3是帶有大小的標頭,2是消息,3是校驗和。 但是,接收所有這些NULL而不是任何有用的信息會使我感到反感。

有人對可能發生的事情有所了解嗎? 我對服務器的控制為零,我只能相信服務器按規定發送了這些消息。

服務器向您發送消息的大小。 您必須利用此優勢。 另外,您定義功能的方式也很難報告錯誤。 您應該考慮這樣的事情:

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

我僅為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上。 否則,我會得到沒有意義的信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM