2011-10-13 76 views
1

我是Objective C的新手,并且正在为发送UDP数据包的Titanium框架修改iOS模块。该模块当前允许您传入一个文本字符串进行发送,并将其转换为字节并通过UDP将其发送到目标IP和端口。这个伟大工程,这里是代码:如何将NSNumbers的NSArray转换为NSData

https://github.com/chrisfjones/titanium_module_udp/blob/master/UDPSocketProxy.m

我想要做的就是传递一个字节数组到发送功能,而不是一个字符串,并有它只是发送。这里是二码:

var udp = require('chrisfjones.titanium_module_udp'); 
var socket = udp.createUDP(); 
var bytes = [ 100, 15, 132, 53, 14, 246, 0, 0, 0, 0, 196, 209, 1, 1, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 16, 0, 45, 120, 0, 0, 0, 0, 158, 4, 111, 30, 179, 41 ]; 
socket.send(bytes, "1.2.3.4", 6100); 

这里是迄今为止新的发送功能:

- (void) sendBytes: (NSArray*) args { 

    NSArray *msg  = (NSArray*)[args objectAtIndex: 0]; 

    NSString *host  = [TiUtils stringValue:[args objectAtIndex: 1]]; 

    NSInteger port  = [TiUtils intValue: [args objectAtIndex: 2]]; 


NSLog(@"%@ send bytes: %@ to %@:%i", self, msg, host, port); 


struct sockaddr_in destinationAddress; 

    socklen_t sockaddr_destaddr_len = sizeof(destinationAddress); 



    memset(&destinationAddress, 0, sockaddr_destaddr_len); 

    destinationAddress.sin_len = (__uint8_t) sockaddr_destaddr_len; 

    destinationAddress.sin_family = AF_INET; 

    destinationAddress.sin_port = htons(port); 

    destinationAddress.sin_addr.s_addr = inet_addr([host cStringUsingEncoding: NSUTF8StringEncoding]); 



    NSData *destinationAddressData = [NSData dataWithBytes:&destinationAddress length:sizeof(destinationAddress)]; 



    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:msg]; 



    CFSocketError socket_error = CFSocketSendData(_socket, (CFDataRef) destinationAddressData, (CFDataRef) data, 10); 

    if (socket_error) { 

     NSLog(@"socket error: %li", socket_error); 

    } else { 

     NSLog(@"sent bytes: '%@' to %@:%i", msg, host, port); 

    } 

} 

,它通过在NSArray中你会注意到。这是因为Titanium将我创建的javascript数组转换为NSNumber对象的NSArray。我读到这是非常低效的,但是它内置到Titanium框架中,所以我没有看到它的解决方法,所以我希望得到一个关于如何使它在这个过程中得到通过的答案,而不是关于如何使用它的一个讲座效率低下。

当我调用新的发送方法,而不是发送我传入的50个左右的字节时,我可以在wireshark中看到它实际上传递了超过1000个字节。我假设的问题是在这条线的转换:

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:msg]; 

可有人请就如何只发送的字节数组,我通过帮助?谢谢!

回答

3

是的,在这种情况下,您不想使用存档器,因为您只是想将一组字节转换为NSData的块。根据您传递的是NSNumber的数组还是NSString的数组,您基本上需要遍历数组的内容并将数据追加到NSMutableData

假设它是NSNumber一个数组,那么这样的事情应该工作:

NSMutableData *data = [[NSMutableData alloc] initWithCapacity: [msg count]]; 
for(NSNumber *number in msg) { 
    char byte = [number charValue]; 
    [data appendBytes: &byte length: 1]; 
} 
// .... code that uses data ... 
[data release]; 

如果数字字符串形式的数值,你可能会想使用的NSString-(int)intValue方法拔出数据然后添加到数据,基本上改变了上面:

NSMutableData *data = [[NSMutableData alloc] initWithCapacity: [msg count]]; 
for(NSString *string in msg) { 
    char byte = (char)[string intValue]; 
    [data appendBytes: &byte length: 1]; 
} 
// .... code that uses data ... 
[data release]; 

而且,如果你想从东西字符串中的字符,那么你就需要抓住用的字符并补偿您将收到unichar而不是char的事实。

+0

很好,谢谢!有一点变化,第一行和第二行的“参数”应该是“味精”。 – Justin

+0

谢谢。现在已修好。 – gaige