23
23
NSString* SocketMessageIdKey = @"SocketMessageId";
24
24
NSString* SocketMessageDataKey = @"SocketMessageData";
26
const int kSocketMessengerTerminateMsg = -1;
26
29
@interface SocketMessenger (Private)
27
30
- (void) startCommsWorkThreads;
31
- (void) startWatchdogThread;
32
- (void) startListening;
30
35
@implementation SocketMessenger
95
104
FD_SET(socket, &readfds);
96
105
FD_SET(socket, &errorfds);
97
106
maxSocket = MAX(maxSocket, socket);
101
//printf("No sockets, sleeping for a bit...\n");
106
108
if (select(maxSocket+1, &readfds, &writefds, &errorfds, &tv) < 0)
108
110
perror("select");
114
if (FD_ISSET(socket, &errorfds))
112
118
if (FD_ISSET(socket, &readfds))
130
136
else if (actuallyRead == -1)
132
//close(commsSocket);
133
//self->commsSocket = 0;
134
138
if (errno != ETIMEDOUT)
136
140
printf("Connection dropped with error.\n");
140
144
else if (actuallyRead == 0)
142
146
printf("remote socket closed.\n");
146
150
if (!expectedMessageSize)
194
//NSLog(@"dataReceived (%d) #%d", (int) [currentData length], currentMessageId);
186
196
if (receiveDataOnMainThread)
187
[self performSelectorOnMainThread: @selector(dataReceived:) withObject: [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: currentMessageId], SocketMessageIdKey, currentData, SocketMessageDataKey, nil] waitUntilDone: NO];
197
[delegate performSelectorOnMainThread: @selector(dataReceived:) withObject: [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: currentMessageId], SocketMessageIdKey, currentData, SocketMessageDataKey, nil] waitUntilDone: NO];
189
[self dataReceived: [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: currentMessageId], SocketMessageIdKey, currentData, SocketMessageDataKey, nil]];
199
[delegate dataReceived: [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: currentMessageId], SocketMessageIdKey, currentData, SocketMessageDataKey, nil]];
191
201
currentData = nil;
192
202
currentlyRead = 0;
212
self->commsSocket = -1;
198
219
[self threadWillExit: info];
200
221
@synchronized(self)
216
237
id number = [NSNumber numberWithInt: threadIds++];
218
239
[activeThreads setObject: [NSNumber numberWithBool: YES] forKey: number];
219
[NSThread detachNewThreadSelector: selector toTarget: self withObject: [number retain]];
240
[NSThread detachNewThreadSelector: selector toTarget: target withObject: [number retain]];
270
293
socket = commsSocket;
296
//printf("sending %d bytes\n", (int) sizeToSend);
273
298
while (dataSent < sizeToSend)
275
300
if ((err = send(socket, header + dataSent, sizeToSend - dataSent, 0)) == -1)
319
- (void) connectToService: (NSNetService*) service
352
- (void) connectToRemoteService
321
NSInteger port = [service port];
322
NSString* hostName = [service hostName];
354
NSInteger port = [remoteService port];
355
NSString* hostName = [remoteService hostName];
324
357
NSLog(@"SocketMessenger attempting to connect to %@ : %d", hostName, port);
378
413
self->commsSocket = sockfd;
380
415
[self startCommsWorkThreads];
416
[self startWatchdogThread];
420
- (void) connectToService: (NSNetService*) service
423
[remoteService release];
424
remoteService = service;
425
[self connectToRemoteService];
428
- (void) stopCommsWorkThreads
430
while (rxThreadActive || txThreadActive)
432
rxThreadShouldRun = 0;
433
txThreadShouldRun = 0;
441
- (void) stopWatchdogThread
443
while (wdThreadActive)
445
wdThreadShouldRun = 0;
450
- (void) startWatchdogThread
452
//[self stopWatchdogThread];
456
wdThreadShouldRun = 1;
461
[self runThreadWithTarget: self selector: @selector(watchdogThread:)];
465
- (void) stopAcceptThread
467
while (server.acThreadActive)
469
server.acThreadShouldRun = 0;
474
- (void) startAcceptThread
476
[self stopAcceptThread];
478
server.acThreadShouldRun = 1;
479
server.acThreadActive = 1;
481
[self runThreadWithTarget: self selector: @selector(acceptThread:)];
384
485
- (void) startCommsWorkThreads
386
[self runThreadWithSelector: @selector(sendingThread:)];
387
[self runThreadWithSelector: @selector(receivingThread:)];
389
if ([self respondsToSelector: @selector(connectionWasEstablished)])
390
[self connectionWasEstablished];
487
[self stopCommsWorkThreads];
489
rxThreadShouldRun = 1;
491
txThreadShouldRun = 1;
494
[self runThreadWithTarget: self selector: @selector(sendingThread:)];
495
[self runThreadWithTarget: self selector: @selector(receivingThread:)];
497
if ([delegate respondsToSelector: @selector(connectionWasEstablished:)])
498
[delegate performSelectorOnMainThread: @selector(connectionWasEstablished:) withObject: self waitUntilDone: NO];
393
501
static void _setStandardSocketOpts(int socket)
430
538
FD_SET(lsock, &readfds);
431
539
FD_SET(lsock, &errorfds);
432
540
maxSocket = MAX(maxSocket, lsock);
436
printf("No sockets, sleeping for a bit...\n");
441
542
//NSLog(@"listening for connection...");
443
544
if (select(maxSocket+1, &readfds, NULL, &errorfds, &tv) < 0)
445
546
perror("select");
482
585
[server.netService release];
483
586
server.netService = nil;
588
close(server.listenSocket);
589
server.listenSocket = -1;
485
591
[self startCommsWorkThreads];
487
593
NSLog(@"Accepted connection.");
602
close(server.listenSocket);
603
server.listenSocket = -1;
610
server.acThreadActive = 0;
621
- (void) watchdogThread: (id) info
623
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
630
while (wdThreadShouldRun)
634
if ((commsSocket == -1) && (server.listenSocket == -1))
636
NSLog(@"watchdog noticed connection error");
637
if (automaticallyReconnect)
639
NSLog(@"restarting server");
640
[self stopCommsWorkThreads];
641
[self startListening];
645
if ([delegate respondsToSelector: @selector(connectionWasTerminated:)])
646
[delegate performSelectorOnMainThread: @selector(connectionWasTerminated:) withObject: self waitUntilDone: NO];
653
if (commsSocket == -1)
655
NSLog(@"watchdog noticed connection error");
656
if (automaticallyReconnect)
658
NSLog(@"restarting client");
659
[self stopCommsWorkThreads];
660
[self connectToRemoteService];
664
if ([delegate respondsToSelector: @selector(connectionWasTerminated:)])
665
[delegate performSelectorOnMainThread: @selector(connectionWasTerminated:) withObject: self waitUntilDone: NO];
492
685
@synchronized(self)
509
702
assert([protocol length] && server.listenSocket);
511
NSLog(@"tappity port: %d", ntohs(server.myAddress.sin_port));
704
NSLog(@"tappity port: %d", server.portnum);
513
706
[server.netService stop];
514
707
[server.netService release];
516
server.netService = [[NSNetService alloc] initWithDomain: domain type: protocol name: name port: ntohs(server.myAddress.sin_port)];
709
server.netService = [[NSNetService alloc] initWithDomain: domain type: protocol name: name port: server.portnum];
517
710
if(server.netService == nil)
520
[server.netService setDelegate:self];
713
[server.netService setDelegate: self];
521
714
// [server.netService scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
522
715
[server.netService publish];
528
722
- (void) startListening
530
server.myAddress.sin_family = AF_INET; // host byte order
531
server.myAddress.sin_port = htons(server.portnum); // short, network byte order, any port
532
server.myAddress.sin_addr.s_addr = htonl(INADDR_ANY); // auto-fill with my IP
724
struct sockaddr_in myAddress;
725
memset(&myAddress, 0, sizeof(myAddress));
727
myAddress.sin_family = AF_INET; // host byte order
728
myAddress.sin_port = htons(server.portnum); // short, network byte order, any port
729
myAddress.sin_addr.s_addr = htonl(INADDR_ANY); // auto-fill with my IP
534
731
server.listenSocket = socket(PF_INET, SOCK_STREAM, 0);
535
732
assert(server.listenSocket != -1);
537
734
_setStandardSocketOpts(server.listenSocket);
539
int err = bind(server.listenSocket, (struct sockaddr *)&server.myAddress, sizeof(server.myAddress));
736
int err = bind(server.listenSocket, (struct sockaddr *)&myAddress, sizeof(myAddress));
540
737
assert(-1 != err);
542
739
err = listen(server.listenSocket, 1);
543
740
assert(-1 != err);
545
[self runThreadWithSelector: @selector(acceptThread:)];
742
[self startAcceptThread];
743
[self startWatchdogThread];
547
745
if([self enableBonjourWithDomain: @"" applicationProtocol: server.protocolName name: server.serviceName])
548
746
NSLog(@"tappity bounjour advertisments up and running");
561
759
server.protocolName = [protocol retain];
563
761
server.portnum = pnum;
565
765
[self startListening];
769
- (void) terminateConnection
771
[self stopWatchdogThread];
772
[self stopAcceptThread];
773
[self stopCommsWorkThreads];
571
779
[server.serviceName release];
573
781
[server.netService stop];