


MultipeerConnectivity.frameworkiOS 7.0OS X 10.10
可以看到基於MC可以做到電腦與手機的通信。 了解了其能力與SDK相關信息後,下面我們看看工作流程: 使設備可被發現--->浏覽設備,建立連接--->傳輸數據 。 關於使用大家可以看看參考資源與 MCDemo, 這裡只是做一個代碼導讀。
-(void)setupPeerAndSessionWithDisplayName:(NSString *)displayName{
_peerID = [[MCPeerID alloc] initWithDisplayName:displayName];
_session = [[MCSession alloc] initWithPeer:_peerID];
_session.delegate = self;
}
-(void)advertiseSelf:(BOOL)shouldAdvertise{
if (shouldAdvertise) {
_advertiser = [[MCAdvertiserAssistant alloc] initWithServiceType:@chat-files
discoveryInfo:nil
session:_session];
[_advertiser start];
}
else{
[_advertiser stop];
_advertiser = nil;
}
}
-(void)setupMCBrowser{
_browser = [[MCBrowserViewController alloc] initWithServiceType:@chat-files session:_session];
}
-(void)sendMyMessage{
NSData *dataToSend = [_txtMessage.text dataUsingEncoding:NSUTF8StringEncoding];
NSArray *allPeers = _appDelegate.mcManager.session.connectedPeers;
NSError *error;
[_appDelegate.mcManager.session sendData:dataToSend
toPeers:allPeers
withMode:MCSessionSendDataReliable
error:&error];
if (error) {
NSLog(@%@, [error localizedDescription]);
}
[_tvChat setText:[_tvChat.text stringByAppendingString:[NSString stringWithFormat:@I wrote:
%@
, _txtMessage.text]]];
[_txtMessage setText:@];
[_txtMessage resignFirstResponder];
}
-(void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID{
NSDictionary *dict = @{@data: data,
@peerID: peerID
};
[[NSNotificationCenter defaultCenter] postNotificationName:@MCDidReceiveDataNotification
object:nil
userInfo:dict];
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex != [[_appDelegate.mcManager.session connectedPeers] count]) {
NSString *filePath = [_documentsDirectory stringByAppendingPathComponent:_selectedFile];
NSString *modifiedName = [NSString stringWithFormat:@%@_%@, _appDelegate.mcManager.peerID.displayName, _selectedFile];
NSURL *resourceURL = [NSURL fileURLWithPath:filePath];
dispatch_async(dispatch_get_main_queue(), ^{
NSProgress *progress = [_appDelegate.mcManager.session sendResourceAtURL:resourceURL
withName:modifiedName
toPeer:[[_appDelegate.mcManager.session connectedPeers] objectAtIndex:buttonIndex]
withCompletionHandler:^(NSError *error) {
if (error) {
NSLog(@Error: %@, [error localizedDescription]);
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@MCDemo
message:@File was successfully sent.
delegate:self
cancelButtonTitle:nil
otherButtonTitles:@Great!, nil];
[alert performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:NO];
[_arrFiles replaceObjectAtIndex:_selectedRow withObject:_selectedFile];
[_tblFiles performSelectorOnMainThread:@selector(reloadData)
withObject:nil
waitUntilDone:NO];
}
}];
//NSLog(@*** %f, progress.fractionCompleted);
[progress addObserver:self
forKeyPath:@fractionCompleted
options:NSKeyValueObservingOptionNew
context:nil];
});
}
}
-(void)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress{
NSDictionary *dict = @{@resourceName : resourceName,
@peerID : peerID,
@progress : progress
};
[[NSNotificationCenter defaultCenter] postNotificationName:@MCDidStartReceivingResourceNotification
object:nil
userInfo:dict];
dispatch_async(dispatch_get_main_queue(), ^{
[progress addObserver:self
forKeyPath:@fractionCompleted
options:NSKeyValueObservingOptionNew
context:nil];
});
}







void * -[MCPeerID initWithDisplayName:](void * self, void * _cmd, void * arg2) {
STK33 = r5;
STK35 = r7;
sp = sp - 0x28;
r5 = arg2;
arg_20 = self;
arg_24 = *0x568f0;
r6 = [[&arg_20 super] init];
if (r6 != 0x0) {
if ((r5 == 0x0) || ([r5 length] == 0x0)) {
r0 = [r6 class];
r0 = NSStringFromClass(r0);
var_0 = r0;
[NSException raise:*_NSInvalidArgumentException format:@Invalid displayName passed to %@];
}
else {
if ([r5 lengthOfBytesUsingEncoding:0x4] >= 0x40) {
r0 = [r6 class];
r0 = NSStringFromClass(r0);
var_0 = r0;
[NSException raise:*_NSInvalidArgumentException format:@Invalid displayName passed to %@];
}
}
arg_8 = r6;
arg_C = r5;
r8 = CFUUIDCreate(*_kCFAllocatorDefault);
CFUUIDGetUUIDBytes(&arg_10);
r11 = (arg_1C ^ arg_14) << 0x18 | (arg_1C ^ arg_14) & 0xff00 | 0xff00 & (arg_1C ^ arg_14) | arg_1C ^ arg_14;
r10 = 0xff00 & (arg_10 ^ arg_18) | ((arg_10 ^ arg_18) & 0xff00) << 0x8 | arg_10 ^ arg_18 | arg_10 ^ arg_18;
r5 = _makebase36string(r11, r10);
if (*_gVRTraceErrorLogLevel < 0x6) {
asm{ strd r4, r5, [sp] };
VRTracePrint_();
}
else {
if (*(int8_t *)_gVRTraceModuleFilterEnabled != 0x0) {
asm{ strd r4, r5, [sp] };
VRTracePrint_();
}
}
r4 = [NSString stringWithUTF8String:r5];
free(r5);
CFRelease(r8);
r0 = [MCPeerIDInternal alloc];
var_0 = r10;
arg_4 = arg_C;
r0 = [r0 initWithIDString:r4 pid64:r11 displayName:STK-1];
r6 = arg_8;
r6->_internal = r0;
}
r0 = r6;
Pop();
Pop();
Pop();
return r0;
}
[[MCPeerIDInternal alloc] initWithIDString:_makebase36string(...) pid64:r11 displayName:STK-1]




-- Apple Mutipeer Connectivity Custom DTLS Protocl
-- cache globals to local for speed.
local format = string.format
local tostring = tostring
local tonumber = tonumber
local sqrt = math.sqrt
local pairs = pairs
-- wireshark API globals
local Pref = Pref
local Proto = Proto
local ProtoField = ProtoField
local DissectorTable = DissectorTable
local Dissector = Dissector
local ByteArray = ByteArray
local PI_MALFORMED = PI_MALFORMED
local PI_ERROR = PI_ERROR
-- dissectors
local dtls_dissector = Dissector.get(dtls)
apple_mcdtls_proto = Proto(apple_mcDTLS, Apple Multipeer Connectivity DTLS, Apple Multipeer Connectivity DTLS Protocol)
function apple_mcdtls_proto.dissector(buffer, pinfo, tree)
local mctype = buffer(0, 1):uint()
if mctype == 208 then
pinfo.cols.protocol = AppleMCDTLS
pinfo.cols.info = Apple MC DTLS Payload Data
local subtree = tree:add(apple_mcdtls_proto, buffer(), Apple MC DTLS Protocol)
subtree:add(buffer(0, 1),Type: .. buffer(0, 1):uint())
local size = buffer:len()
subtree:add(buffer(1, size - 1), Data: .. tostring(buffer))
dtls_dissector:call(buffer(1):tvb(), pinfo, tree)
end
end
local function unregister_udp_port_range(start_port, end_port)
if not start_port or start_port <= 0 or not end_port or end_port <= 0 then
return
end
udp_port_table = DissectorTable.get(udp.port)
for port = start_port,end_port do
udp_port_table:remove(port, apple_mcdtls_proto)
end
end
local function register_udp_port_range(start_port, end_port)
if not start_port or start_port <= 0 or not end_port or end_port <= 0 then
return
end
udp_port_table = DissectorTable.get(udp.port)
for port = start_port,end_port do
udp_port_table:add(port, apple_mcdtls_proto)
end
end
register_udp_port_range(16400, 16499)


