2013-11-02 98 views
0

我正在寫一個snmp客戶端,它通過UDP端口161連接到網絡服務器。它將發送一個ASN格式的消息,並將接收來自服務器的響應。我試過了所有我能想到的,但我似乎無法正常工作。UDP snmp客戶端問題Java

該程序是應該接收並解析出計數器字段從以下命令中CMD返回:

SNMPGET -d -v 2C -c公共129.130.10.43 ip.ipInReceives.0

//命令的結果:

{

發送43個字節到UDP:[129.130.10.43]:161 - > [0.0.0.0]

0000:30 29 02 01 0 1 04 06 70 75 62 6C 69 63 A0 02 1C 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 49 1B 95 0C + ....... A..I ..

IP-MIB :: ipInReceives.0 =計數器:457772181

}

//我ASN消息格式化筆記:

十六進制值保存在一個byte []數組和通給UDP服務器:

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 XX的將被改變(可能隨機),以創造獨特的請求ID

代碼:

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,(字符*)類,43,0,(結構sockaddr *)& serv_addr,servlen); 他的代碼通過相同的十六進制代碼完美工作。

我能想到的唯一的事情是,我沒有格式化,發送,或聽正確的,但澆過的文檔和例子之後,我找不出任何東西了。有沒有人有一些指針?

+0

如果您有權訪問教授的示例,請嘗試與自己的示例一起運行它,並使用Wireshark或tcpdump等工具來查看兩種情況下實際發送的內容。如果有任何內容正在發送,您可以看到程序發送的內容不同。 – sdanzig

+0

我必須通過膩子在Linux服務器上遠程運行教授的示例,並且我不知道如何獲取wireshark。我在外發數據包上做了一個捕獲,並且一切都看起來完全正確(目的地是好的,端口是161,郵件正文很好等),但是我沒有從wireshark的服務器得到任何迴應。我不知道發生了什麼事。 – kcducttaper

+0

您可以在Linux服務器上嘗試tcpdump。它不像用戶友好,但它仍然非常簡單。快速谷歌或查看它的手冊頁會告訴你如何使用它。 – sdanzig

回答

0

如果您的問題縮小到十六進制字符串字節數組轉換,這裏亞去:

轉換十六進制字符串爲一個字節數組,在Java

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; 
} 
+0

其實,我的函數調用該方法),這是不正確的。我的一些數據字節被錯誤地用這種方法轉換(雖然我不確定爲什麼,現在我也不太在意)。我結束了使用'DatatypeConverter.parseHexBinary(str);'獲取十六進制字符串的byte []表示。 – kcducttaper

0

我想通出。我用來將我的十六進制字符串轉換爲byte []的方法工作不正確。我切換到使用內置的轉換器「DatatypeConverter.parseHexBinary(str);」它工作得很好。

+0

當我在服務器上運行它時,我得到了某種迴應,但是我似乎無法解開它以瞭解它。該機器上似乎沒有安裝tcpdump,所以我很難判斷數據包中實際發送了什麼。這是我得到的輸出: 「java.net.DatagramPacket中@(7或8炭化長度十六進制字符串)」,其中所述十六進制字符串出現,如果我的消息是唯一的或不 或 0而不考慮隨機)public * square * 3 * square * 00 + PuTTy 我可以使用receivedPacket.getData()。toString()提取某種數字,但它看起來不正確。 – kcducttaper