我使用GCDAsyncSocket创建了一个简单的客户端服务器应用程序。
主机通过bonjour广播其服务,客户端连接到它,然后每个客户端向主机发送特定信息,在主机完成请求后,它现在应该能够将每个请求发送到其相应的客户端。
当客户端在完成请求之前断开连接(可能重启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];
}
有没有人知道我该如何解决这种客户端 - 主机信息交换?
答案 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
}