0

UDP ポート 161 経由でネットワーク サーバーに接続する snmp クライアントを作成しています。ASN 形式のメッセージを送信し、サーバーからの応答を受信します。考えられることはすべて試しましたが、うまく動作しないようです。

プログラムは、cmd の次のコマンドから返されたカウンター フィールドを受け取り、解析することになっています。

snmpget -d -v 2c -c public 129.130.10.43 ip.ipInReceives.0

// コマンドの結果:

{

UDP に 43 バイトを送信: [129.130.10.43]:161->[0.0.0.0]

0000: 30 29 02 01 01 04 06 70 75 62 6C 69 63 A0 1C 02 0).....パブリック...

0016: 04 28 6A DF 1F 02 01 00 02 01 00 30 0E 30 0C 06 .(j........0.0..

0032: 08 2B 06 01 02 01 04 03 00 05 00 .+........

UDP から 47 バイトを受信しました: [129.130.10.43]:161->[0.0.0.0]

0000: 30 2D 02 01 01 04 06 70 75 62 6C 69 63 A2 20 02 0-.....公開。.

0016: 04 28 6A DF 1F 02 01 00 02 01 00 30 12 30 10 06 .(j........0.0..

0032: 08 2B 06 01 02 01 04 03 00 41 04 1B 49 0C 95 .+.......A..I..

IP-MIB::ipInReceives.0 = Counter32: 457772181

}

//my asn メッセージの書式に関する注意事項:

byte[] 配列に保存して udp サーバーに渡す 16 進値:

30 29 02 01 01 04 06 70 75 62 6C 69 63 A0 1C 02

04 XX XX XX XX 02 01 00 02 01 00 30 0E 30 0C 06

08 2B 06 01 02 01 04 03 00 05 00

XX はリクエスト ID を示します。一意のリクエスト ID を作成するために、リクエストごとに XX が変更されます (おそらくランダム化されます)。

コード:

  public static void snmpMessage() throws SocketException
{
    DatagramSocket socket = null;
    byte[] serverResponse = new byte[1024];
    InetAddress addy = null;        
    byte[] hex = hexStringToByteArray("302902010004067075626C6963A01C0204121533EA020100020100300E300C06082B060102010403000500"); //note: this hex string is the exact string from the example program, so I know the string is correct
    addy = InetAddress.getByName("129.130.10.48"); //server IP address
    socket= new DatagramSocket();

    //method that creates unique snmp asn message replacing the XX's with appropriate non-negative hex values       
    hex = messageGenerator();

    //Data reproduction from byte[] array
    System.out.println("byte array integer format:\n" + Arrays.toString(hex)); //correctly prints out integer values        
    System.out.println("\nbyte array length: " + hex.length); //Correctly prints length of sending array (43)
    System.out.println("\nserver name: " + addy.getCanonicalHostName()); //correctly prints server name        
    String hex2 = toHex(hex);        
    System.out.println("\nbyte array in hex format: \n" + hex2); //correctly reproduces original hex string from byte[] array

    //at this point, I can only assume that my data is stored correctly
    //send byte array to server
    DatagramPacket sendPacket = new DatagramPacket(hex, hex.length, addy, 161);
        socket.send(sendPacket);                

    //get server's response
    DatagramPacket receivePacket = new DatagramPacket(serverResponse, serverResponse.length);       
        System.out.println("\nWaiting for server response...\n"); //prints out
        socket.receive(receivePacket);
        System.out.println("Response received"); //does not print
}

私の教授は、ポインターを単純に char 文字列に渡す例を投稿しました: sendto (sockfd, (char *) s, 43, 0, (struct sockaddr *) &serv_addr, servlen); 同じ 16 進コードを渡す彼のコードは完全に機能します。

私が考えることができる唯一のことは、私が正しくフォーマット、送信、またはリッスンしていないということですが、ドキュメンテーションと例を注ぎ込んだ後、何も理解できません. 誰かがいくつかの指針を持っていますか?

4

2 に答える 2

0

私はそれを考え出した。16 進文字列を byte[] に変換するために使用していた方法が、正しく機能していませんでした。組み込みのコンバーター「DatatypeConverter.parseHexBinary(str);」を使用するように切り替えました。そしてそれはうまくいきました。

于 2013-11-03T02:04:28.347 に答える
0

問題を16進文字列からバイト配列への変換に絞り込んだ場合は、次のようになります。

Java での 16 進文字列のバイト配列への変換

public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}
于 2013-11-02T21:31:10.520 に答える