使用GCDAyncSocket将任意信息与套接字相关联

时间:2014-08-29 17:06:23

标签: objective-c tcp gcdasyncsocket

我使用GCDAsyncSocket创建了一个简单的客户端服务器应用程序。

主机通过bonjour广播其服务,客户端连接到它,然后每个客户端向主机发送特定信息,在主机完成请求后,它现在应该能够将每个请求发送到其相应的客户端。

enter image description here

当客户端在完成请求之前断开连接(可能重启WiFi)并再次连接时,其连接的主机和端口可能会发生变化。

因此,我拒绝客户端,我想在字典中存储已连接客户端的列表

key : vendorID (specific to each client and can't change)
value :  connected host and port (gcdAsyncSocket instance) 

如何使用套接字发送任意信息(vendorID)?

似乎GCDAsyncSocket有一个名为UserData的属性,我在客户端中使用vendorID设置它 但是在主机中它是空的。

客户端:

- (BOOL)connectWithService:(NSNetService *)service {
BOOL _isConnected = NO;

// Copy Service Addresses
NSArray *addresses = [[service addresses] mutableCopy];

if (!self.socket || ![self.socket isConnected]) {
    // Initialize Socket


       self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

        //adding deviceID to sockect to identify connected clients in the host

        self.socket.userData = @"vendorID2308746238764021";

        // Connect
        while (!_isConnected && [addresses count]) {
            NSData *address = [addresses objectAtIndex:0];
            NSError *error = nil;

            if ([self.socket connectToAddress:address error:&error]) {
                _isConnected = true;
            }

            else if (error) {
                NSLog(@"Unable to connect to address. Error %@ with user info %@.", error, [error userInfo]);
            }
        }

    } else {
        _isConnected = [self.socket isConnected];
    }

    return _isConnected;
}

主机:

- (void)socket:(GCDAsyncSocket *)socket didAcceptNewSocket:(GCDAsyncSocket *)newSocket {
    NSLog(@"Accepted New Socket from %@:%hu", [newSocket connectedHost], [newSocket connectedPort]);

    //both userData is null!
    NSLog(@"%@",newSocket.userData);
    NSLog(@"%@",socket.userData);
    //adding new socket to the list of connected clients
    //using ip and port of the scoket as key
    [self.clients setObject:newSocket forKey:[NSString stringWithFormat:@"%@-%d", [newSocket connectedHost], [newSocket connectedPort]]];
    // Notify Delegate
    [self.delegate tcpHost:self didHostClientOnSocket:newSocket];
}

有没有人知道我该如何解决这种客户端 - 主机信息交换?

1 个答案:

答案 0 :(得分:1)

ClientSide:在我的TCPClient类中,当客户端连接到服务器时,我发送的第一个数据包是身份数据包:

//server can identify  device
- (void)sendIdentity
{
    NSData *identifcationData = [[UIDevice deviceID] dataUsingEncoding:NSUTF8StringEncoding];
    HAPacket *packet = [[HAPacket alloc] initWithData:identifcationData type:HAPacketTypeIdentity action:HAPacketActionUnknown];
    [self sendPacket:packet];
}

服务器:获取此数据包并识别客户端 在TCPHost中:客户端连接后,我将其存储在临时数组中。 在socket:didReadData我检查:

if (tag == TAG_BODY) {

    //first packet is always for identifaction. if client has not identified, its id is empty
    Client *unknownClient = [[self.temp linq_where:^BOOL(Client *client)
                              {
                                  return client.ID == nil || [client.ID isEqualToString: @""];
                              }] linq_firstOrNil];

    if (unknownClient && (unknownClient.ID == nil || [unknownClient.ID  isEqualToString: @""])) {
        NSLog(@"identifying client...");
        [self identifyClient:unknownClient withData:data];
    }
    else
{
// parse the packet as usual
}