cra sh при чтении данных сокета - recv () - в target- c - PullRequest
2 голосов
/ 17 апреля 2020

Я пытаюсь прочитать данные из сокета, и в большинстве случаев он работает нормально.

Когда я запускаю приложение на более длительный срок - приложение вылетает и аварийно завершает работу, указывая sh на readSocket ( ) - эта функция просто считывает необработанные данные из сокета.

Ниже приведен код readSocket ()

-(bool) readingSocket:(NSMutableData*)dataIn readBytes:(ssize_t)quantity error:(NSError **)error {

    ssize_t readBytesNow = 0;
    ssize_t grossRead= 0;

    [dataIn setLength:0];
    if (error != nil) {
        *error = nil;
    }

    char *buffer = new char[6144];

do {
    ssize_t readBytes = (quantity - grossRead);
    readBytesNow = recv((int)raw_Socket, buffer, readBytes , MSG_DONTWAIT);

    if (readBytesNow == 0) {
            NSLog(@" read error");

            delete[] buffer;
            return false;
    }
    Else if (bytesRead < 0) {
            if (errno == EAGAIN) {

                [NSThread sleepForTimeInterval:0.5f];
                 NSLog(@" EAGAIN error");

                continue;
            }
            else {
                // if error != nil
                delete[] buffer;
                return false;
            }
     }
     else if (readBytesNow > 0) {

          grossRead += readBytesNow;
           // doing some operations

    }

} while (grossRead < quantity);



delete[] buffer;
return true;

}

Я уже делаю так много проверок после чтения, но не уверен, где это возможно причина для cra sh или исключения ??

любой другой лучший способ обработки исключения в моем коде выше?

1 Ответ

0 голосов
/ 27 апреля 2020

Я не могу комментировать без 50 репутации (новый пользователь здесь), поэтому здесь идет мой комментарий в качестве ответа.

Предупреждение: я понятия не имею, на каком языке написан ваш код, но я используя мои инстинкты как программист на C ++ (и, вероятно, посредственный в этом).

Первое, что я заметил, был следующий фрагмент кода:

if (error != nil) {
    *error = nil;
}

В мире C это было бы аналогично проверке, является ли указатель нулевым, но впоследствии присваивает ему значение в качестве значения.

Второе, на что следует обратить внимание, это конструкция:

-(bool) readingSocket:(NSMutableData*)dataIn readBytes:(ssize_t)quantity error:(NSError **)error {
...
char *buffer = new char[6144];
...
ssize_t readBytes = (quantity - grossRead);

Когда количество> 6144, т. е. один раз в голубой луне Ваш сетевой стек может прочитать более 6144 байтов, что приведет к переполнению буфера.

Тангенциальные комментарии:

1) Я думаю, вы должны заметить, что EAGAIN и EWOULDBLOCK может иметь одинаковое значение, но не гарантируется. Вы можете рассмотреть возможность проверки их обоих, если не уверены, что ваша платформа ведет себя именно так, как вы думаете.

Пример ссылки на Linux документацию

2) Ваши логики c,

if (readBytesNow == 0) {
...
} Else if (bytesRead < 0) {
...
} else if (readBytesNow > 0) {
...
}

, хотя и являются многословными, не нужны. Вы можете использовать

if (readBytesNow == 0) {
...
} Else if (bytesRead < 0) {
...
} else {
...
}

, чтобы убедиться, что вы не получаете дополнительное сравнение. Это сравнение может быть оптимизировано в любом случае, но писать таким образом имеет больше смысла. Мне пришлось снова посмотреть, чтобы увидеть, «если я что-то упустил».

Надеюсь, что это поможет.

...