writeData auf einem Syncsocket blockiert immer auf dem iPhone
-
27-10-2019 - |
Frage
Ich verwende das Asyncsocket-Beispiel als Ausgangspunkt, um mehr über die WLAN-Kommunikation auf dem iPhone zu erfahren.
Auf dem Mac starte ich einen Beispielserver, der Port 0 öffnet. Dies funktioniert, da ich Daten mit einem Testclient schreiben kann, der auf dem Mac ausgeführt wird.
Auf dem iPhone konnte ich eine Verbindung herstellen, da "Streams verbunden" JA zurückgibt.
Dann möchte ich Daten mit einem Syncsocket senden: (BEARBEITETE VERSION MIT KOMPLETTEM CODE)
import "InterfaceTestAppDelegate.h"
import "InterfaceTestViewController.h"
import "AsyncSocket.h"
import "SyncSocket.h"
@implementation InterfaceTestAppDelegate
@synthesize window;
@synthesize viewController;
(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)remoteHost port:(UInt16)remotePort { NSLog(@"Socket is connected!");
NSLog(@"Remote Address: %@:%hu", remoteHost, remotePort);
NSString *localHost = [sock localHost]; UInt16 localPort = [sock localPort];
NSLog(@"Local Address: %@:%hu", localHost, localPort); }
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSLog(@"application:didFinishLaunchingWithOptions:");
/* asyncSocket = [[AsyncSocket alloc] initWithDelegate:self];
NSError *err = nil; if (![asyncSocket connectToHost: @"192.168.0.30" onPort: 1234 error: &err]) { NSLog(@"Error connecting: %@", err); } NSData *data = [@"testxyz" dataUsingEncoding:NSUTF8StringEncoding]; NSLog(@"trace 1"); [asyncSocket writeData:data withTimeout:10 tag:0]; NSLog(@"trace 2");
*/ syncSocket = [[SyncSocket alloc] initWithTimeout: 10]; syncSocket.nsLog = YES; if (![syncSocket connectToHost: @"192.168.0.30" onPort: 12345]) { NSLog(@"Error connecting syncSocket:"); } NSData *data = [@"testxyz" dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"syncSocket trace 1"); [syncSocket writeData:data]; NSLog(@"syncSocket trace 2");
[Fenster addSubview: viewController.view]; [window makeKeyAndVisible]; JA zurückgeben; }
Die Daten werden nie weiter gesendet, die writeData werden immer blockiert. Die IP 192.168.0.30 ist die IP meines Mac. Ich habe gerade einen Port 12345 verwendet, wie Sie oben vorgeschlagen haben.
Aber ich weiß nicht wirklich, was ich auf dem Mac tun muss, um zu empfangen?
Wie Sie sehen, verwende ich tatsächlich Syncsocket, dann blockiert es.
Ich habe auch asyncSocket ausprobiert, dann erhalte ich die Meldung in der asyncsocket-Klasse: writeStream kann keine Bytes akzeptieren
Vielleicht ist es so, dass ich den Mac nicht richtig eingerichtet habe, dh welche App muss ich zum Testen auf dem Mac ausführen? Vielen Dank!
Lösung
Für das, was es wert ist, lesen Sie in der Regel einige Daten mit AsyncSocket ein:
-(void)onSocket:(AsyncSocket *)sock
didReadData:(NSData*)data withTag:(long)tag
{
[data getBytes:&getMe length:sizeof(CommProt)];
// now, you must roll in the next read...
[sock readDataToLength:sizeof(CommProt) withTimeout:-1 tag:0];
// CommProt is your communications protocol, so sizeof(CommProt)
// is how much to read at a chunk.
// you can now simply access the fields of getMe,
// for example getMe.x, getMe.y, getMe.latestValue etc etc.
// hope it helps!
}
Natürlich hätten Sie zuvor den ersten "Primer" -Lesebefehl ausgeführt:
Sie tun dies, wenn Sie eine Verbindung zu einem Host herstellen, daher:
-(void)onSocket:(AsyncSocket *)sock
didConnectToHost:(NSString *)host port:(UInt16)port
{
if ( yourAppSaysItsOkToConnectAtThisMoment == NO )
{
[sock disconnect]; // (so easy, AsyncSockets is a masterpiece)
return;
}
// .. blah blah
// the critical 'primer' read command
[sock readDataToLength:sizeof(CommProt) withTimeout:-1 tag:0];
// .. blah blah
}
Vergessen Sie nicht, dass Sie beim nächsten Lesevorgang an zwei Stellen rollen müssen, (a) beim ersten Verbinden und (b) natürlich nach jedem Lesevorgang!
Im Beispiel würde Ihr Kommunikationsprotokoll so aussehen ...
typedef struct _CommProt // v.3
{
BOOL pressExplosionButton;
BOOL pressFireworksButton;
float usersSteering;
float usersTemperature;
float usersAltitude;
float usersAngle;
}
CommProt;
Eine Variable wie "getMe" im Beispiel würde einfach so aussehen:
CommProt getMe;
CommProt sendMe;
Wenn Sie Schwierigkeiten haben, diese Art von Kommunikationsprotokoll zu verstehen, versuchen Sie auch diese lange Antwort:
Tablet (iPad / Android) -Server-Kommunikationsprotokoll
AsyncSocket ist unglaublich schön, es wurde von dem mysteriösen Justin Voss geschrieben, der das Internet zu verlassen schien, nachdem er es der Welt gegeben hatte - es ist eine der besten Bibliotheken, die jemals geschrieben wurden, es ist ein Meisterwerk.
Hoffe es hilft.