inet_ntoaの典型的な誤用
linux
//(N行を省く......)char*source、*dest;struct in_addr saddr; struct in_addr daddr; saddr.s_addr = (in_addr_t)cmd.source.v_uint;//cmd.source.v_uintは文字列からinet_を介してロードされましたaton()が変換したソースIPのネットワークバイトは、ここで間違いなく、深く究明する必要はありません:)daddr.s_addr = (in_addr_t)cmd.dest.v_uint;//同上source=(char*)inet_ntoa(saddr); dest = (char*)inet_ntoa(daddr); printf(“source[%s] dest[%s]”,source,dest);//(N行省略…)実行後の印刷結果は、常にソースIPと宛先IPが同じであり、以下のようになる(プログラム名はpro)#./Pro-s 192.1.1-d 192.2.2.2#source[192.2.2.2]dest[192.2.2.2]は長い間何の間違いも発見されていないことを検査して、最初は値をつける時うっかりソースIPを目的IPに割り当てたと思っていたが、実際に書く時はやはり注意深く、このような間違いを犯していない.最後の一歩一歩を調べてsaddr.s_addrとdaddr.s_addrの数値が印刷され、両者の数値が全く異なることが分かった.両者が異なる以上、inet_を通じてntoa()が返す文字列も違うはずなので、問題はinet_ntoa()の応用になりました.manさん、気づいたよinet_ntoaのこの行は、
The inet_ntoa() function converts the Internet host address in, givenin network byte order, to a string in IPv4 dotted-decimal notation.The string is returned in a statically allocated buffer, which subse-quent calls will overwrite.赤いフォントの意味はinet_ntoa()が返す文字列は、静的に割り当てられたバッファに一時的に組み込まれ、次の関数が呼び出されるとバッファが書き換えられます.ははは、なぜ文字列に変換されたのか、ソースアドレスは常に宛先アドレスと同じであることがやっと分かった.肝心な原因はポインタの使用であり、ソースアドレスと宛先アドレス文字列をロードするためのsourceとdestをポインタとして宣言することであり、値を付与すると両者のポインタはinet_を指すntoa()の一時バッファではdestに値を付与するとバッファが書き換えられるのでsourceポインタの値が目的アドレスになり,両者は自然に同じになる.したがって、次のコードに変更すれば問題ありません.
//(依然としてN行を省く…)char source[16]、dest[16];//配列として宣言すると、バッファからコンテンツをコピーできます.フェースはバッファint saddr_をポインタで指すのではありません.len,daddr_len; struct in_addr saddr; struct in_addr daddr; saddr.s_addr = (in_addr_t)cmd.source.v_uint; daddr.s_addr = (in_addr_t)cmd.dest.v_uint; saddr_len = strlen(inet_ntoa(saddr)); daddr_len = strlen(inet_ntoa(daddr)); if(saddr_len<=15&&daddr_len<=15)/IPアドレスの文字列は最大15ビット{memcpy(source,inet_ntoa(saddr),saddr_len);memcpy(dest,inet_ntoa(daddr),daddr_len);source[saddr_len]='/0';dest[daddr_len]='/0';else{ printf("ADDR Error/n"); exit(1); } printf(“source[%s] dest[%s]”,source,dest);//(相変わらずN行は省く・・・)
家电で说明书を読まないことに惯れました.これからは物を使う前に説明をよく見て、回り道をしないようにしましょう.