0

私はネットワークアプリケーションで作業しています...しかし、ネットワーク経由で送信する前に、データのパッキングとアンパッキングをテストしています...しかし、多くのガベージ値を取得しています

ui テキスト フィールド内の myfield .. 私のラベルは uilabel です ... ボタンが押されると mybutton メソッドが呼び出されます

rec メソッドでは、x の値 (ガベージ) は -231231223432.... から +3423423423..... まで変化します。

また、このデータを nsstring にパックしたい場合、どのようにパックおよびアンパックしますか?

 enum 
{
gkMessageSent,
gkMessageNotsent
};


-(void)rec:(NSData *)data
 {

const char *incomingPacket = (const char *)[data bytes];
char messageType = incomingPacket[0];

switch (messageType)
{


    case gkMessageSent: 
    {  


        float x = *(float *)(incomingPacket + 1 );
        // value of x are not correct here
        NSString *resultString = [[NSString alloc] initWithFormat:@"%f",x];

        mylabel.text= resultString;            

        break;
    }

    case gkMessageNotsent: 
    { 
        mylabel.text=@"2";
        break;
    }  

        default:
        mylabel.text=@"3";
        break;


}



 }


 -(IBAction)mybutton{


   float myvalue=[myfield.text floatValue];

    // i check myvalue here and its fine

NSMutableData *data= [NSMutableData dataWithCapacity:1+sizeof(float)];


int myrand=1+rand()%3;

if(myrand==1)
{
    char messageType = gkMessageSent;  
    [data appendBytes:&messageType length:1];


    [data appendBytes:&myvalue length:sizeof(float)];




}
else {
    char messageType = gkMessageNotsent;
    [data appendBytes:&messageType length:1];
    [data appendBytes:&myvalue length:sizeof(float) ];        


}


[self rec:data];  


 }

いくつかの調査の後、NSStringをNSmutabledataにパックする方法を見つけましたが、アンパックを理解できません

-(IBAction)mybutton {






   float myvalue=300;


NSString *resultString = [[NSString alloc] initWithFormat:@"%.2f",myvalue];



NSMutableData *data=nil;

data= [NSMutableData dataWithCapacity:1+([resultString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]) ];


int myrand=1+rand()%3;

if(myrand==1)
{
    char messageType = gkMessageSent;  
    [data appendBytes:&messageType length:1];

    [data appendBytes:[resultString UTF8String] length:[resultString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];           



}
else {
    char messageType = gkMessageNotsent;
    [data appendBytes:&messageType length:1];

    [data appendBytes:[resultString UTF8String] length:[resultString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];         

    }


[self rec:data];   


}



-(void)rec:(NSData *)data{

const char *incomingPacket = (const char *)[data bytes];
char messageType = incomingPacket[0];

switch (messageType)
{


    case gkMessageSent: 
    {  


       // Have to get the String here

        break;
    }

    case gkMessageNotsent: 
    { 
        mylabel.text=@"2";
        break;
    }  

        default:
        mylabel.text=@"3";
        break;


}



}
4

1 に答える 1

0

サイズが不明な「生の」データをネットワーク経由で送信しないでください。整数を使用している場合は、データを生で送信するのではなく、バイト順を「ネットワーク順」に「修正」してから、反対側でプロセスを逆にすることでデータを送信できます。

uint32t foo = htonl(myLong);

それを逆にするには:

uint32t myLong = ntohl(networkData4bytesLong);

float と double は強制的に上記を使用できますが、(私の知る限り)これを行う標準的な方法はありません。次のハックが機能するためには、float が両側で 32 ビット IEEE 形式の型でなければなりません (現在、ほとんどのシステムでおそらくそうです)。

1 つの方法は、long と float を含む共用体を作成することです。

struct foo {
  uint32_t lng;
  float flt;
};

おそらく assert(sizeof(foo) == 4); を追加する必要があります。念のため、両側にも。

float をこのタイプの共用体に入れてから、htonl(foo.lng); を使用します。変換し、反対側でそれを逆にします。

おそらく、より信頼性の高い (しかしより難しい方法) は、float を文字列に変換し、それを送信してから、浮動小数点型に戻すことです。とはいえ、上記はリストされた仮定 (IEEE、32 ビット タイプ) でうまくいくはずです。

編集: したがって、文字列を使用する場合は、送信するデータに null で終了する文字列を追加するか、最初のバイトが長さであり、null で終了しない文字列が続く「パスカル」型の文字列を使用するか、または少なくとも 1 つの終端 NULL を持つ一定量のスペースを許可できます。簡潔にするために、3 番目の方法を使用しますが、コーディングする場合はおそらく「パスカル」方法が最適です。

したがって、十分なスペースがあることを 100% 確実にするために、float に 20 バイトを割り当てます (多すぎます)。

char floatStr[20];
sprintf(floatStr, "%f", myFloat);
[myData appendBytes:floatStr length:20];

反対側:

unsigned char *ptr = ...; // set to the start of the string
sscanf(ptr, "%f", &myFloat);
ptr += 20;
于 2012-08-27T21:53:36.283 に答える