【问题标题】:crash while reading the socket data - recv() - in objective-c在 Objective-C 中读取套接字数据时崩溃 - recv()
【发布时间】:2020-07-30 19:56:00
【问题描述】:

我正在尝试从套接字读取数据,并且大部分时间都可以正常工作。

当我运行应用程序更长的时间时 - 应用程序崩溃和 crashlytics 将崩溃指向 readingSocket() - 这个函数只是从套接字读取原始数据。

下面是readingSocket()的代码

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

}

阅读后我已经做了很多检查,但不确定导致崩溃或异常的可能原因在哪里??

还有其他更好的方法来处理我上面的代码中的异常吗?

【问题讨论】:

    标签: ios sockets exception crash recv


    【解决方案1】:

    如果没有 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 个字节,这将导致缓冲区溢出。

    切向 cmets:

    1) 我认为您应该注意 EAGAIN 和 EWOULDBLOCK 可能是相同的值,但不能保证。如果您不确定您的平台是否与您想象的完全一样,您可以考虑同时检查它们。

    An example link to Linux documentation

    2) 你的逻辑,

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

    虽然冗长,但没有必要。你可以使用

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

    以确保您没有得到额外的比较。无论如何,这种比较可能会得到优化,但这样写更有意义。我不得不再次查看“如果我遗漏了什么”。

    希望这些帮助。

    【讨论】:

      猜你喜欢
      • 2019-08-16
      • 1970-01-01
      • 1970-01-01
      • 2012-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-23
      相关资源
      最近更新 更多