recv возвращает старые данные - PullRequest
2 голосов
/ 28 апреля 2010

Этот цикл должен собирать данные из сокета построчно и помещать их в буфер.По какой-то причине, когда нет новых данных для возврата, recv возвращает последние пару строк, которые он получил.Мне удалось остановить ошибку, закомментировав первый recv, но потом я не могу сказать, какой длины будет следующая строка.Я знаю, что это не

while(this->connected){
    memset(buf, '\0', sizeof(buf));
    recv(this->sock, buf, sizeof(buf), MSG_PEEK);           //get length of next message
    ptr = strstr(buf, "\r\n");
    if (ptr == NULL) continue;
    err = recv(this->sock, buf, (ptr-buf), NULL);    //get next message

    printf("--%db\n%s\n", err, buf);

    tok[0] = strtok(buf, " ");
    for(i=1;tok[i-1]!=NULL;i++) tok[i] = strtok(NULL, " ");

//do more stuff
}

Ответы [ 4 ]

1 голос
/ 28 апреля 2010

Ваша проблема в том, что когда вы используете recv с MSG_PEEK, вы даете recv полный размер вашего буфера, если там уже есть две строки, например, "HELLO \ r \ nHELLO \ r \ n", он будет читать их в ваш бафф.

ptr будет указывать на первый \ r \ n, затем вы вызываете recv с помощью (ptr - buff), который заставит recv читать только первый HELLO в buf, но, поскольку вы уже СЧИТАЕТЕ эту информацию в buff, вы обработаете два строк, но оставив \ r \ nHELLO \ r \ n в вашей очереди, потому что вы не полностью прочитали их.

В следующий раз вы загляните в него и получите информацию, которая уже обработана, что заставит вас поверить, что вы получаете повторяющиеся данные.

(Надеюсь, я написал это достаточно ясно, это очень запутанная ошибка, которую вы получили:)

1 голос
/ 28 апреля 2010

Мне нужно было добавить 2 к длине второго recv, чтобы я взял "\ r \ n". В противном случае он видит первый «\ r \ n» и считает, что строка конца - это buf [0].

1 голос
/ 28 апреля 2010

руководство заявляет:

MSG_PEEK Этот флаг заставляет операцию приема возвращать данные из начало очереди приема без удаляя эти данные из очереди. Таким образом, последующий прием вызова будет вернуть те же данные.

Так что я думаю, что вы получаете правильное поведение, но, возможно, ожидаете чего-то другого.

0 голосов
/ 07 ноября 2017

Привет, я нахожу решение:

void receiver(int accepted_client) {
// Ready to receive data from client.
while (true) {
    char buffer[256];
    recv(accepted_client, &buffer, 255, 0);
    int sum = 0;
    for (int i = 0; i < 256; i++) // Check that buffer value is zero or not.
        sum |= buffer[i];

    if (sum != 0) {// If buffer value is not zero then start to print the new received message.
        string string_message(buffer);
        cout << string_message << endl;
    }
    memset(&buffer, 0, 256); // Clear the buffer.
  }
}
...