1

Objective C は初めてで、UDP パケットを送信する Titanium フレームワーク用の iOS モジュールを変更しています。このモジュールでは現在、送信するテキスト文字列を渡すことができ、それをバイトに変換し、UDP 経由で宛先 IP とポートに送信します。これはうまく機能し、コードは次のとおりです。

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);

これまでの新しい send 関数は次のとおりです。

- (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 フレームワークに組み込まれているため、回避する方法がわかりません。そのため、どのように講義するのではなく、これを渡して機能させる方法についての回答を期待しています。非効率です。

新しい send メソッドを呼び出すと、渡す 50 バイト程度を送信する代わりに、実際に 1000 バイト以上を渡していることを Wireshark で確認できます。問題はこの行の変換にあると思います:

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:msg];

渡すバイト配列を送信する方法について誰か助けてもらえますか? ありがとう!

4

2 に答える 2

3

はい、この場合はアーカイバを使用したくありません。バイトのセットを のブロックに変換しようとしているだけだからですNSDataNSNumberの配列または の配列のどちらを渡すかに応じて、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];

数値が文字列形式の数値である場合は、 の-(int)intValue方法を使用NSStringしてデータを取り出し、それをデータに追加して、基本的に上記を次のように変更することをお勧めします。

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];

また、文字列から文字を詰め込もうとしている場合は、 を使用して文字を取得し、 の代わりに を[string characterAtIndex: 0]受け取るという事実を補う必要があります。unicharchar

于 2011-10-14T00:05:24.683 に答える