Я использую методы sendto/recvfrom для отправки/получения UDP-пакетов в моем приложении. Теперь мой получить метод заключается в следующем:Почему возвращаемое значение из метода recvfrom равно 4294967295, которое должно быть 0 или -1?
- (void)listenForPackets
{
int listeningSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (listeningSocket <= 0) {
NSLog(@"Error: listenForPackets - socket() failed.");
return;
}
// set timeout to 2 seconds
struct timeval timeV;
timeV.tv_sec = 2;
timeV.tv_usec = 0;
if (setsockopt(listeningSocket, SOL_SOCKET, SO_RCVTIMEO, &timeV, sizeof(timeV)) == -1) {
NSLog(@"Error: listenForPackets - setsockopt failed");
close(listeningSocket);
return;
}
// bind the port
struct sockaddr_in sockaddr;
memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_len = sizeof(sockaddr);
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(18686);
sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
int status = bind(listeningSocket, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
if (status == -1) {
close(listeningSocket);
NSLog(@"Error: listenForPackets - bind() failed.");
return;
}
// receive
struct sockaddr_in receiveSockaddr;
socklen_t receiveSockaddrLen = sizeof(receiveSockaddr);
size_t bufSize = 9216;
void *buf = malloc(bufSize);
size_t result = recvfrom(listeningSocket, buf, bufSize, 0, (struct sockaddr *)&receiveSockaddr, &receiveSockaddrLen);
NSData *data = nil;
if (result > 0) {
NSLog(@"reslut:%zu",result);
if (result != bufSize) {
buf = realloc(buf, result);
}
data = [NSData dataWithBytesNoCopy:buf length:result freeWhenDone:YES];
char addrBuf[INET_ADDRSTRLEN];
if (inet_ntop(AF_INET, &receiveSockaddr.sin_addr, addrBuf, (size_t)sizeof(addrBuf)) == NULL) {
addrBuf[0] = '\0';
}
NSString *address = [NSString stringWithCString:addrBuf encoding:NSASCIIStringEncoding];
NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
dispatch_async(dispatch_get_main_queue(), ^{
[self didReceiveMessage:msg fromAddress:address];
});
} else {
free(buf);
}
close(listeningSocket);
}
когда я нажмите на одну кнопку я пошлю один UDP вещания и вызвать вышеописанный метод для прослушивания. В начале я не использовал setsockopt(listeningSocket, SOL_SOCKET, SO_RCVTIMEO, &timeV, sizeof(timeV))
для установки тайм-аута в приеме. но при нажатии более одного раза будет ошибка привязки. Возможно, первый из них все еще прослушивает порт и не завершен. поэтому я добавляю второй тайм-аут, чтобы убедиться, что предыдущий закончен. Однако, когда я устанавливаю тайм-аут, значение результата выше, это 4294967295. а затем вызывает сбой в моем приложении. Журнал аварии ниже:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSConcreteData initWithBytes:length:copy:deallocator:]: absurd length: 4294967295, maximum size: 2147483648 bytes'
*** First throw call stack:
(0x2ed14e83 0x390716c7 0x2ed14dc5 0x2f64799b 0x2f63fe53 0x2f63fd4d 0x2f64dbab 0x2f64db69 0x13cffb 0x13cdb3 0x395560c3 0x3955b7d9 0x3955b9c5 0x39685dff 0x39685cc4)
libc++abi.dylib: terminating with uncaught exception of type NSException
почему возвращаемое значение 4294967295 вместо 0 или -1, если установить тайм-аут? Как это исправить? Любое предложение было бы очень оценено.
спасибо за ваш ответ – chancyWu
Правильный тип: 'ssize_t' (« тип размера подписи »), а не' int'. –
@MartinR Вы правы, спасибо за исправление. – KudoCC