我正在尝试从套接字读取数据,并且在大多数情况下都可以正常工作。
[当我运行该应用程序的时间更长-应用程序崩溃且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;
}
阅读后我已经进行了很多检查,但不确定崩溃或异常的可能原因在哪里?
上面的代码中还有其他更好的处理异常的方法吗?
没有50个声誉我无可奉告(这里是新用户),因此我的评论将作为答案。
警告:我不知道您的代码是用哪种语言编写的,但是我是作为C ++程序员使用我的直觉(可能是普通的)。
我注意到的第一件事是这段代码:
if (error != nil) {
*error = nil;
}
在C语言世界中,这类似于检查指针是否为null,但之后将其值赋为null。
要注意的第二件事是此构造:
-(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可以是相同的值,但不能保证。如果不确定您的平台行为是否完全符合您的想象,则可以考虑同时检查它们。
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 {
...
}
确保没有其他比较。无论如何,这种比较可能会得到优化,但是以这种方式编写更有意义。我不得不再次查看以查看“如果我缺少某些东西”。
希望这些帮助。