Mam problem z rozwojem serwera/klienta TCP w celu c z Bonjour.Klient serwera tcp NSOS iS NSStream nie może komunikować się
Po stronie serwera poprawnie otwieram strumienie i używam funkcji handleEvent do wysyłania i odbierania danych. Ale nie wiem, jaki jest właściwy sposób wysyłania i odbierania danych. Czytałem ten doskonały wpis: Correct way to send data through a socket with NSOutputStream więc korzystać z systemu pakietów w kolejce do wysyłania danych:
switch(eventCode) {
case NSStreamEventOpenCompleted: {
NSLog(@"Complete");
} break;
case NSStreamEventHasSpaceAvailable: {
if (stream == _outputStream)
[self _sendData];
} break;
...
- (void)_sendData {
flag_canSendDirectly = NO;
NSData *data = [_dataWriteQueue lastObject];
if (data == nil) {
flag_canSendDirectly = YES;
return;
}
uint8_t *readBytes = (uint8_t *)[data bytes];
readBytes += currentDataOffset;
NSUInteger dataLength = [data length];
NSUInteger lengthOfDataToWrite = (dataLength - currentDataOffset >= 1024) ? 1024 : (dataLength - currentDataOffset);
NSInteger bytesWritten = [_outputStream write:readBytes maxLength:lengthOfDataToWrite];
currentDataOffset += bytesWritten;
if (bytesWritten > 0) {
self.currentDataOffset += bytesWritten;
if (self.currentDataOffset == dataLength) {
[self.dataWriteQueue removeLastObject];
self.currentDataOffset = 0;
}
}
}
. Więc po prostu wysyłam oddzielne moje dane na wiele pakietów. Ale nie widzę sposobu, aby zrekonstruować dane po stronie klienta. I myślę, że nie zrozumiałem poprawnie zdarzenia NSStreamEventHasBytesAvailable. Ponieważ tutaj wysyłam wiele pakietów, ale to zdarzenie po stronie klienta to wywołanie tylko raz. A kiedy odtwarzam dane z bufora, dane wydają się być uszkodzone. Byłbym bardzo wdzięczny, gdyby ktoś mógł to wszystko wyjaśnić, dokumentacja nie jest bardzo jasna w tym punkcie (a może brakuje mi punktu ...).
case NSStreamEventHasBytesAvailable: {
if (stream == _inputStream)
{
//read data
uint8_t buffer[1024];
int len;
while ([_inputStream hasBytesAvailable])
{
len = [_inputStream read:buffer maxLength:sizeof(buffer)];
if (len > 0)
{
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];
//NSData *theData = [[NSData alloc] initWithBytes:buffer length:len];
UnitySendMessage("AppleBonjour_UnityNetworkManager(Clone)", "OnLocalClientReceiveMessageFromServer", [output cStringUsingEncoding:NSUTF8StringEncoding]);
}
}
}
Czy próbowałeś prosty test? Wyślij pojedynczy krótki ciąg. Co otrzymujesz w swoim zmiennym "wyjściu", kiedy to robisz? fwiw; nie musi być pojedynczego wywołania bajtów dostępnych dla każdego wysłania, będą one połączone, jeśli przyjdą w czasie, a jeden odczyt dostanie je wszystkie. Wypróbuj ten test i powiedz nam, co otrzymujesz. –
Och, zapomniałem o jeszcze jednej rzeczy; możesz przetestować odbiornik za pomocą prostego programu tcp, takiego jak telnet. Wystarczy połączyć się z portem i wpisać tekst. Jeśli kod odbiornika działa, powinieneś otrzymać swój tekst bezpośrednio. –
OK działa prosty ciąg. Więc jeśli wysyłam łańcuch większy niż bufor, po prostu muszę go zrekonstruować za każdym razem, gdy wywoływany jest NSStreamEventHasBytesAvailable. Ale w jaki sposób mogę otrzymać powiadomienie, gdy ciąg zostanie wysłany całkowicie? – thegrandwaazoo