multiple devices on same host/same port

70 views
Skip to first unread message

Nicolas Dahlet

unread,
Jun 16, 2010, 1:36:05 PM6/16/10
to CocoaAsyncSocket
Hi Gang!

I'm currently writting my first app for iPhone and facing a problem
with the AsyncUdpSocket class. Here is the thing:
My appDelegate sets up a udp socket (in a secondary thread), which
sends a first request to the server. Once the server receives that
request, it starts "spitting" data out continuously. My app receives
it, treats it, and displays it on the main thread. It all works
beautifully.
However, as soon as that same app is launched on a second device
(computer, iPhone or iPad), the first device stops receiving and when
getting the error with [udpSocket getSocketError], it gives me the
vague following message:

Error Domain=AsyncUdpSocketErrorDomain Code=-1 "General CFSocket
error" UserInfo=0x1989e0 {NSLocalizedDescription=General CFSocket
error}

Once that happens, it seems impossible to do anything, even after
closing the socket and creating a new one, the new socket giving the
same error.

Here is the code I'm using to create the socket on startup in my
secondary thread:

NSError *error = nil;
int port = 52000;

[udpSocket close];
[udpSocket release];
udpSocket = nil;

udpSocket = [[[AsyncUdpSocket alloc] initWithDelegate:self] retain];
//[udpSocket enableBroadcast:YES error:&error];
//[udpSocket bindToPort:port error:&error];
[udpSocket connectToHost:@"192.168.1.10" onPort:port error:&error];

//[udpSocket setMaxReceiveBufferSize:65536];

unsigned char buf[2];
buf[0] = 0x1F;
buf[1] = 0;

NSData *request = [NSData dataWithBytes:buf length:2];

[udpSocket sendData:request withTimeout:-1 tag:0];


Then:

- (void)onUdpSocket:(AsyncUdpSocket *)sock didSendDataWithTag:
(long)tag
{
[udpSocket receiveWithTimeout:-1 tag:0];
}

And:

- (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData
*)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port
{

if ([lostConnectionTimer isValid])
{
[lostConnectionTimer invalidate];
}

//code where I treat the data and display it on the main thread

[udpSocket receiveWithTimeout:-1 tag:0];

lostConnectionCounter = 0;
lostConnectionTimer = [NSTimer scheduledTimerWithTimeInterval: 0.1
target: self
selector: @selector(watchReceive)
userInfo: nil
repeats: YES];

return YES;
}

-(void) watchReceive
{
NSLog(@"lostConnectionCounter:%i",lostConnectionCounter);

if (lostConnectionCounter > 1)
{
NSLog(@"udpSocket:%@",[[udpSocket getSocketError] description]);

NSError *error = nil;
int port = 52000;

[udpSocket close];
[udpSocket release];
udpSocket = nil;

AsyncUdpSocket *newUdpSocket = [[[AsyncUdpSocket alloc]
initWithDelegate:self] retain];
//[newUdpSocket enableBroadcast:YES error:&error];
//[newUdpSocket bindToPort:port error:&error];
[newUdpSocket connectToHost:@"192.168.1.10" onPort:port
error:&error];
[newUdpSocket receiveWithTimeout:-1 tag:1];

NSLog(@"newUdpSocket:%@",[[newUdpSocket getSocketError]
description]);
}

lostConnectionCounter += 1;
}


Any help on this would be greatly appreciated!

Thanks gang!

Nicolas.

Nicolas Dahlet

unread,
Jun 18, 2010, 10:26:27 AM6/18/10
to CocoaAsyncSocket
As it turns out, I wasn't aware of all the ins & outs of the UDP
protocol. The "connectToHost:onPort:error:" apparently results in an
exclusive relationship between the server and the client, kicking out
other clients previously connected to the server on the same host and
port.
The best solution I found is making the server broadcast messages, and
then enable the broadcast with the "enableBoradcast:error" method.

However, when enabling broadcast, I've noticed a significant drop of
processing speed on first and second generation devices (in my case,
an Ipod Touch 2,1 compared to an iPad). I'm guessing that once the
broadcast is enabled, all the IP addresses are being scanned by the
device, making it slower.

I hope this will help some other novice like me in the future!

Cheers!

Nicolas.
Reply all
Reply to author
Forward
0 new messages