飛鴿傳書(IP Messenger,簡為IPMsg)是一個小巧方便的即時通信軟件,它適合用于局域網內甚至廣域網間進行實時通信和文檔共享。特別是在局域網內傳送文件/文件夾的速度非常快!
本文演示了如何使用Java的net包,向IPMSG客戶端發送消息。
IPMSG Command 常量定義如下:
IPMSG收發數據包的格式(一行):
示例(向IPMSG發送消息,需要先打開對方的IPMSG):
你可以在 SourceForge 找到開源的 IP MSG for Java
從本Blog 下載
http://www.aygfsteel.com/tripper
- IPMsg 是一款局域網內即時通信軟件, 基于 TCP/IP(UDP).
- 可運行于多種操作平臺(Win/Mac/UNIX/Java), 并實現跨平臺信息交流.
- 不需要服務器支持.
- 支持文件/文件夾的傳送 (2.00版以上)
- 通訊數據采用 RSA/Blofish 加密 (2.00版以上)
- 十分小巧, 簡單易用, 而且你可以完全免費使用它
- 目前已有的版本包括: Win32, Win16, MacOS, MacOSX, X11, GTK, GNOME,Java 等, 并且公開源代碼。
本文演示了如何使用Java的net包,向IPMSG客戶端發送消息。
IPMSG Command 常量定義如下:
?1?/*==========?Constant?Value?==========*/
?2?public?static?final?long?IPMSG_COMMASK?=?0x000000ff;
?3?public?static?final?long?IPMSG_OPTMASK?=?0xffffff00;
?4?public?static?final?long?IPMSG_NOOPERATION?=?0x00000000;
?5?public?static?final?long?IPMSG_BR_ENTRY?=?0x00000001;
?6?public?static?final?long?IPMSG_BR_EXIT?=?0x00000002;
?7?public?static?final?long?IPMSG_ANSENTRY?=?0x00000003;
?8?public?static?final?long?IPMSG_BR_ABSENCE?=?0x00000004;
?9?
10??
11?
12?public?static?final?long?IPMSG_BR_ISGETLIST?=?0x00000018;
13?public?static?final?long?IPMSG_OKGETLIST?=?0x00000015;
14?public?static?final?long?IPMSG_GETLIST?=?0x00000016;
15?public?static?final?long?IPMSG_ANSLIST?=?0x00000017;
16?
17?public?static?final?long?IPMSG_SENDMSG?=?0x00000020;
18?public?static?final?long?IPMSG_RECVMSG?=?0x00000021;
19?
20?public?static?final?long?IPMSG_READMSG?=?0x00000030;
21?public?static?final?long?IPMSG_DELMSG?=?0x00000031;
22?
23?public?static?final?long?IPMSG_GETINFO?=?0x00000040;
24?public?static?final?long?IPMSG_SENDINFO?=?0x00000041;
25?
26?//?other?opt
27?public?static?final?long?IPMSG_ABSENCEOPT?=?0x00000100;
28?public?static?final?long?IPMSG_SERVEROPT?=?0x00000200;
29?public?static?final?long?IPMSG_DIALUPOPT?=?0x00010000;
30?
31?//?send?opt
32?public?static?final?long?IPMSG_SENDCHECKOPT?=?0x00000100;
33?public?static?final?long?IPMSG_SECRETOPT?=?0x00000200;
34?public?static?final?long?IPMSG_BROADCASTOPT?=?0x00000400;
35?public?static?final?long?IPMSG_MULTICASTOPT?=?0x00000800;
36?public?static?final?long?IPMSG_NOPOPUPOPT?=?0x00001000;
37?public?static?final?long?IPMSG_AUTORETOPT?=?0x00002000;
38?public?static?final?long?IPMSG_RETRYOPT?=?0x00004000;
39?public?static?final?long?IPMSG_PASSWORDOPT?=?0x00008000;
40?public?static?final?long?IPMSG_NOLOGOPT?=?0x00020000;
41?public?static?final?long?IPMSG_NEWMUTIOPT?=?0x00040000;
42?
43?public?static?final?int?MAXBUF?=?8192;
44?/*==========?end?==========*/
?2?public?static?final?long?IPMSG_COMMASK?=?0x000000ff;
?3?public?static?final?long?IPMSG_OPTMASK?=?0xffffff00;
?4?public?static?final?long?IPMSG_NOOPERATION?=?0x00000000;
?5?public?static?final?long?IPMSG_BR_ENTRY?=?0x00000001;
?6?public?static?final?long?IPMSG_BR_EXIT?=?0x00000002;
?7?public?static?final?long?IPMSG_ANSENTRY?=?0x00000003;
?8?public?static?final?long?IPMSG_BR_ABSENCE?=?0x00000004;
?9?
10??
11?
12?public?static?final?long?IPMSG_BR_ISGETLIST?=?0x00000018;
13?public?static?final?long?IPMSG_OKGETLIST?=?0x00000015;
14?public?static?final?long?IPMSG_GETLIST?=?0x00000016;
15?public?static?final?long?IPMSG_ANSLIST?=?0x00000017;
16?
17?public?static?final?long?IPMSG_SENDMSG?=?0x00000020;
18?public?static?final?long?IPMSG_RECVMSG?=?0x00000021;
19?
20?public?static?final?long?IPMSG_READMSG?=?0x00000030;
21?public?static?final?long?IPMSG_DELMSG?=?0x00000031;
22?
23?public?static?final?long?IPMSG_GETINFO?=?0x00000040;
24?public?static?final?long?IPMSG_SENDINFO?=?0x00000041;
25?
26?//?other?opt
27?public?static?final?long?IPMSG_ABSENCEOPT?=?0x00000100;
28?public?static?final?long?IPMSG_SERVEROPT?=?0x00000200;
29?public?static?final?long?IPMSG_DIALUPOPT?=?0x00010000;
30?
31?//?send?opt
32?public?static?final?long?IPMSG_SENDCHECKOPT?=?0x00000100;
33?public?static?final?long?IPMSG_SECRETOPT?=?0x00000200;
34?public?static?final?long?IPMSG_BROADCASTOPT?=?0x00000400;
35?public?static?final?long?IPMSG_MULTICASTOPT?=?0x00000800;
36?public?static?final?long?IPMSG_NOPOPUPOPT?=?0x00001000;
37?public?static?final?long?IPMSG_AUTORETOPT?=?0x00002000;
38?public?static?final?long?IPMSG_RETRYOPT?=?0x00004000;
39?public?static?final?long?IPMSG_PASSWORDOPT?=?0x00008000;
40?public?static?final?long?IPMSG_NOLOGOPT?=?0x00020000;
41?public?static?final?long?IPMSG_NEWMUTIOPT?=?0x00040000;
42?
43?public?static?final?int?MAXBUF?=?8192;
44?/*==========?end?==========*/
IPMSG收發數據包的格式(一行):
1?version(IPMSG版本):no(消息編號,可以用系統時間):user(發送消息的用戶名):host(發送消息的主機名):command(上述?Command?常量,可以用?|?組合多個值):msg(消息內容)
示例(向IPMSG發送消息,需要先打開對方的IPMSG):
?1?import?java.io.IOException;
?2?import?java.net.DatagramPacket;
?3?import?java.net.DatagramSocket;
?4?import?java.net.InetAddress;
?5?import?java.net.SocketException;
?6?import?java.net.UnknownHostException;
?7?import?java.util.Date;
?8?
?9?/**
10??*?@author?亂?7?8?糟?http://www.fadesky.com
11??*/
12?public?class?TestIPMSG
13?{
14???public?static?void?main(String[]?args)
15???{
16?????DatagramSocket?socket;
17?????InetAddress?address;
18?
19?????long?IPMSG_SENDMSG?=?0x00000020;
20?
21?????String?SENDER?=?"亂?7?8?糟";
22?????String?HOST?=?"Localhost";
23?????String?MSG_CONTENT?=?"Hello?World!";
24?
25?????try
26?????{
27???????socket?=?new?DatagramSocket();
28???????address?=?InetAddress.getByName("192.168.1.20");// 發送給消息的地址
29?
30???????/**
31????????*?IPMSG收發數據包的格式(一行):
32????????*?
33????????*?version(IPMSG版本):no(消息編號,可以用系統時間):user(發送消息的用戶名):
34????????*?host(發送消息的主機名):command(上述?Command?常量,可以用?|?組合多個值):
35????????*?msg(消息內容)
36????????*?
37????????*/
38???????byte[]?buffer?=?("1:"?+?new?Date().getTime()?+?":"?+?SENDER?+?":"?+?HOST
39???????????+?":"?+?IPMSG_SENDMSG?+?":"?+?MSG_CONTENT).getBytes();
40?
41???????DatagramPacket?packet?=?new?DatagramPacket(buffer,?buffer.length,
42???????????address,?2425);
43???????socket.send(packet);?//?發送報文
44?
45???????packet?=?new?DatagramPacket(buffer,?buffer.length);
46???????socket.receive(packet);//?接收回應
47?
48???????String?message?=?new?String(packet.getData());?//?得到報文信息
49?
50???????System.out.println(message);?//?顯示對方返回的信息
51?????}
52?????catch?(UnknownHostException?e)
53?????{
54???????e.printStackTrace();
55?????}
56?????catch?(SocketException?e)
57?????{
58???????e.printStackTrace();
59?????}
60?
61?????catch?(IOException?e)
62?????{
63???????e.printStackTrace();
64?????}
65?
66???}
67?
68?}
69?
?2?import?java.net.DatagramPacket;
?3?import?java.net.DatagramSocket;
?4?import?java.net.InetAddress;
?5?import?java.net.SocketException;
?6?import?java.net.UnknownHostException;
?7?import?java.util.Date;
?8?
?9?/**
10??*?@author?亂?7?8?糟?http://www.fadesky.com
11??*/
12?public?class?TestIPMSG
13?{
14???public?static?void?main(String[]?args)
15???{
16?????DatagramSocket?socket;
17?????InetAddress?address;
18?
19?????long?IPMSG_SENDMSG?=?0x00000020;
20?
21?????String?SENDER?=?"亂?7?8?糟";
22?????String?HOST?=?"Localhost";
23?????String?MSG_CONTENT?=?"Hello?World!";
24?
25?????try
26?????{
27???????socket?=?new?DatagramSocket();
28???????address?=?InetAddress.getByName("192.168.1.20");// 發送給消息的地址
29?
30???????/**
31????????*?IPMSG收發數據包的格式(一行):
32????????*?
33????????*?version(IPMSG版本):no(消息編號,可以用系統時間):user(發送消息的用戶名):
34????????*?host(發送消息的主機名):command(上述?Command?常量,可以用?|?組合多個值):
35????????*?msg(消息內容)
36????????*?
37????????*/
38???????byte[]?buffer?=?("1:"?+?new?Date().getTime()?+?":"?+?SENDER?+?":"?+?HOST
39???????????+?":"?+?IPMSG_SENDMSG?+?":"?+?MSG_CONTENT).getBytes();
40?
41???????DatagramPacket?packet?=?new?DatagramPacket(buffer,?buffer.length,
42???????????address,?2425);
43???????socket.send(packet);?//?發送報文
44?
45???????packet?=?new?DatagramPacket(buffer,?buffer.length);
46???????socket.receive(packet);//?接收回應
47?
48???????String?message?=?new?String(packet.getData());?//?得到報文信息
49?
50???????System.out.println(message);?//?顯示對方返回的信息
51?????}
52?????catch?(UnknownHostException?e)
53?????{
54???????e.printStackTrace();
55?????}
56?????catch?(SocketException?e)
57?????{
58???????e.printStackTrace();
59?????}
60?
61?????catch?(IOException?e)
62?????{
63???????e.printStackTrace();
64?????}
65?
66???}
67?
68?}
69?
你可以在 SourceForge 找到開源的 IP MSG for Java
從本Blog 下載
http://www.aygfsteel.com/tripper
IP MSG程序效率寫的很高
可以從CVS下載到。
在Eclipse里新建CVS項目:
CVS地址:
:pserver:anonymous@ipmsg.cvs.sourceforge.net:/cvsroot/ipmsg
我已經打包,添加了下載地址。
可以運行。
至于runtime.properties,在ipmsg.util.IPMPref中,如下:
private static final String HOME_PREF_FILE = ".ipmsg";
...
P_FILE = "runtime.properties";
...
try{
if(new Boolean(pref.getProperty("useHomePrefFile")).booleanValue() &&
(s = System.getProperty("user.home")) != null &&
!s.equals("")){
P_FILE = s + System.getProperty("file.separator") + HOME_PREF_FILE;
}
} catch (MissingResourceException ex) {
ex.printStackTrace();
}
直接在根路徑下編譯:javac *.java
運行:java Main
就可以了。
不過,界面有一部分亂碼,這是因為日文的緣故。
你可以修改:ipmsg\util\Cp932.java
運行后,會在C:\Document and Setting\用戶名 目錄下生成一個.ipmsg的文件。這就是配置文件。
這個Java的版本是比較老了,運行效率也不咋地。
Windows平臺的IPMSG可以收到Java版的IPMSG發送的消息,因為它們發送和接受數據包的格式是一樣的。
不過,我只在 IPMSG 2.06 Winows XP SP2平臺做過測試。
其他版本沒試過。
壓根就沒找到在哪有這個runtime.properties。。。
這個應該不是自己生成的吧
你那有?
發一個出來吧
正常情況下是不會產生這個文件。
請注意下面幾句:
...
P_FILE = "runtime.properties";
...
try
...
//s= "C:\Document and Setting\用戶名"
s = System.getProperty("user.home")
...
//P_FILE = "C:\Document and Setting\用戶名\.ipmsg"
P_FILE = s + System.getProperty("file.separator") + HOME_PREF_FILE;
...
catch(...)
...
正常情況下, P_FILE,也就是配置文件的路徑在try塊中改成了:
"C:\Document and Setting\用戶名\.ipmsg"
如果出現了異常,才使用P_FILE原來的值:"runtime.properties"
就算是改成C:\Document and Setting\用戶名\.ipmsg
也得有這個文件是不
QQ:76551602
你我共同記錄每一個成功的腳步
http://liangyongfei.blogspot.com/
我只用上面的發送消息的示例代碼發送消息后接受的IPmsg(2.06版)沒有任何反映,環境是window2003+jdk1.4.2,接受方為自己或相同環境的另一臺機器都沒有反映。用java版的IPMSG發送消息其他機器的win版可以正常收到。是不是上面的示例代碼需要加上握手過程啊?
看看是代碼執行完了沒有反應,還是一直沒有執行完?
代碼執行完了,執行到
socket.receive(packet);// 接收回應
時會被阻塞,但發送消息的過程已經完成了,將該句注釋掉后程序能從頭到尾執行完而且沒有報錯。
>將該句注釋掉后程序能從頭到尾執行完而且沒有報錯
那么IPMSG可以接收到消息嗎?
>那么IPMSG可以接收到消息嗎?
收不到!
DatagramSocket ds = new DatagramSocket(2425);
byte [] buf=new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
System.out.println(new String(dp.getData(),0,dp.getLength())+" from "+dp.getAddress().getHostAddress()+":"+dp.getPort());
所有懷疑是發送消息的格式問題或是需要先完成“握手”后才能用上面的TestIPMSG來發送消息。請問有人直接用上面的TestIPMSG成功將消息發給其他版本IPMsg的么?
byte[] buffer = ("1:" + new Date().getTime() + ":" + SENDER + ":" + HOST
39 + ":" + IPMSG_SENDMSG + ":" + MSG_CONTENT).getBytes();
你把buffer的值打出來,看看是不是數據格式錯誤(比如不應該出現 : 的地方寫了 : 號)。
String msg="1:"+new Date().getTime()+":"+SENDER+":"+HOST+":"+IPMSG_SENDMSG+":"+MSG_CONTENT;
byte[] buffer =msg.getBytes();
System.out.println("msg="+msg);
System.out.println("buffer="+buffer);
結果是:
msg=1:1180941554265:zhengbowen:AVIDM-ZHENGBW:32:Hello World!
buffer=[B@affc70
1:1180941554265:zhengbowen:AVIDM-ZHENGBW:32:Hello World!
不知道轉為字節后前邊多出來的是什么?
找到原因了 呵呵
轉換后的buffer就是:[B@affc70
而最后一行的:1:1180941554265:zhengbowen:AVIDM-ZHENGBW:32:Hello World! 是下面這就話打出來的:
System.out.println(message); // 顯示對方返回的信息
急
ipmsg.util.Cp932
這個是日文轉碼用的。
方法toJIS(String s)
和toCp932(String s)其實可以不用。
你可以自己調試一下。