2011-10-13 110 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