飛鴿傳書(shū)(IP Messenger,簡(jiǎn)為IPMsg)是一個(gè)小巧方便的即時(shí)通信軟件,它適合用于局域網(wǎng)內(nèi)甚至廣域網(wǎng)間進(jìn)行實(shí)時(shí)通信和文檔共享。特別是在局域網(wǎng)內(nèi)傳送文件/文件夾的速度非???!
本文演示了如何使用Java的net包,向IPMSG客戶端發(fā)送消息。
IPMSG Command 常量定義如下:
IPMSG收發(fā)數(shù)據(jù)包的格式(一行):
示例(向IPMSG發(fā)送消息,需要先打開(kāi)對(duì)方的IPMSG):
你可以在 SourceForge 找到開(kāi)源的 IP MSG for Java
從本Blog 下載
http://www.aygfsteel.com/tripper
- IPMsg 是一款局域網(wǎng)內(nèi)即時(shí)通信軟件, 基于 TCP/IP(UDP).
- 可運(yùn)行于多種操作平臺(tái)(Win/Mac/UNIX/Java), 并實(shí)現(xiàn)跨平臺(tái)信息交流.
- 不需要服務(wù)器支持.
- 支持文件/文件夾的傳送 (2.00版以上)
- 通訊數(shù)據(jù)采用 RSA/Blofish 加密 (2.00版以上)
- 十分小巧, 簡(jiǎn)單易用, 而且你可以完全免費(fèi)使用它
- 目前已有的版本包括: Win32, Win16, MacOS, MacOSX, X11, GTK, GNOME,Java 等, 并且公開(kāi)源代碼。
本文演示了如何使用Java的net包,向IPMSG客戶端發(fā)送消息。
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收發(fā)數(shù)據(jù)包的格式(一行):
1?version(IPMSG版本):no(消息編號(hào),可以用系統(tǒng)時(shí)間):user(發(fā)送消息的用戶名):host(發(fā)送消息的主機(jī)名):command(上述?Command?常量,可以用?|?組合多個(gè)值):msg(消息內(nèi)容)
示例(向IPMSG發(fā)送消息,需要先打開(kāi)對(duì)方的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");// 發(fā)送給消息的地址
29?
30???????/**
31????????*?IPMSG收發(fā)數(shù)據(jù)包的格式(一行):
32????????*?
33????????*?version(IPMSG版本):no(消息編號(hào),可以用系統(tǒng)時(shí)間):user(發(fā)送消息的用戶名):
34????????*?host(發(fā)送消息的主機(jī)名):command(上述?Command?常量,可以用?|?組合多個(gè)值):
35????????*?msg(消息內(nèi)容)
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);?//?發(fā)送報(bào)文
44?
45???????packet?=?new?DatagramPacket(buffer,?buffer.length);
46???????socket.receive(packet);//?接收回應(yīng)
47?
48???????String?message?=?new?String(packet.getData());?//?得到報(bào)文信息
49?
50???????System.out.println(message);?//?顯示對(duì)方返回的信息
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");// 發(fā)送給消息的地址
29?
30???????/**
31????????*?IPMSG收發(fā)數(shù)據(jù)包的格式(一行):
32????????*?
33????????*?version(IPMSG版本):no(消息編號(hào),可以用系統(tǒng)時(shí)間):user(發(fā)送消息的用戶名):
34????????*?host(發(fā)送消息的主機(jī)名):command(上述?Command?常量,可以用?|?組合多個(gè)值):
35????????*?msg(消息內(nèi)容)
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);?//?發(fā)送報(bào)文
44?
45???????packet?=?new?DatagramPacket(buffer,?buffer.length);
46???????socket.receive(packet);//?接收回應(yīng)
47?
48???????String?message?=?new?String(packet.getData());?//?得到報(bào)文信息
49?
50???????System.out.println(message);?//?顯示對(duì)方返回的信息
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 找到開(kāi)源的 IP MSG for Java
從本Blog 下載
http://www.aygfsteel.com/tripper
IP MSG程序效率寫(xiě)的很高
可以從CVS下載到。
在Eclipse里新建CVS項(xiàng)目:
CVS地址:
:pserver:anonymous@ipmsg.cvs.sourceforge.net:/cvsroot/ipmsg
我已經(jīng)打包,添加了下載地址。
可以運(yùn)行。
至于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
運(yùn)行:java Main
就可以了。
不過(guò),界面有一部分亂碼,這是因?yàn)槿瘴牡木壒省?br>你可以修改:ipmsg\util\Cp932.java
運(yùn)行后,會(huì)在C:\Document and Setting\用戶名 目錄下生成一個(gè).ipmsg的文件。這就是配置文件。
這個(gè)Java的版本是比較老了,運(yùn)行效率也不咋地。
Windows平臺(tái)的IPMSG可以收到Java版的IPMSG發(fā)送的消息,因?yàn)樗鼈儼l(fā)送和接受數(shù)據(jù)包的格式是一樣的。
不過(guò),我只在 IPMSG 2.06 Winows XP SP2平臺(tái)做過(guò)測(cè)試。
其他版本沒(méi)試過(guò)。
壓根就沒(méi)找到在哪有這個(gè)runtime.properties。。。
這個(gè)應(yīng)該不是自己生成的吧
你那有?
發(fā)一個(gè)出來(lái)吧
正常情況下是不會(huì)產(chǎn)生這個(gè)文件。
請(qǐng)注意下面幾句:
...
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"
如果出現(xiàn)了異常,才使用P_FILE原來(lái)的值:"runtime.properties"
就算是改成C:\Document and Setting\用戶名\.ipmsg
也得有這個(gè)文件是不
QQ:76551602
你我共同記錄每一個(gè)成功的腳步
http://liangyongfei.blogspot.com/
我只用上面的發(fā)送消息的示例代碼發(fā)送消息后接受的IPmsg(2.06版)沒(méi)有任何反映,環(huán)境是window2003+jdk1.4.2,接受方為自己或相同環(huán)境的另一臺(tái)機(jī)器都沒(méi)有反映。用java版的IPMSG發(fā)送消息其他機(jī)器的win版可以正常收到。是不是上面的示例代碼需要加上握手過(guò)程啊?
看看是代碼執(zhí)行完了沒(méi)有反應(yīng),還是一直沒(méi)有執(zhí)行完?
代碼執(zhí)行完了,執(zhí)行到
socket.receive(packet);// 接收回應(yīng)
時(shí)會(huì)被阻塞,但發(fā)送消息的過(guò)程已經(jīng)完成了,將該句注釋掉后程序能從頭到尾執(zhí)行完而且沒(méi)有報(bào)錯(cuò)。
>將該句注釋掉后程序能從頭到尾執(zhí)行完而且沒(méi)有報(bào)錯(cuò)
那么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());
所有懷疑是發(fā)送消息的格式問(wèn)題或是需要先完成“握手”后才能用上面的TestIPMSG來(lái)發(fā)送消息。請(qǐng)問(wèn)有人直接用上面的TestIPMSG成功將消息發(fā)給其他版本IPMsg的么?
byte[] buffer = ("1:" + new Date().getTime() + ":" + SENDER + ":" + HOST
39 + ":" + IPMSG_SENDMSG + ":" + MSG_CONTENT).getBytes();
你把buffer的值打出來(lái),看看是不是數(shù)據(jù)格式錯(cuò)誤(比如不應(yīng)該出現(xiàn) : 的地方寫(xiě)了 : 號(hào))。
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);
結(jié)果是:
msg=1:1180941554265:zhengbowen:AVIDM-ZHENGBW:32:Hello World!
buffer=[B@affc70
1:1180941554265:zhengbowen:AVIDM-ZHENGBW:32:Hello World!
不知道轉(zhuǎn)為字節(jié)后前邊多出來(lái)的是什么?
找到原因了 呵呵
轉(zhuǎn)換后的buffer就是:[B@affc70
而最后一行的:1:1180941554265:zhengbowen:AVIDM-ZHENGBW:32:Hello World! 是下面這就話打出來(lái)的:
System.out.println(message); // 顯示對(duì)方返回的信息
急
ipmsg.util.Cp932
這個(gè)是日文轉(zhuǎn)碼用的。
方法toJIS(String s)
和toCp932(String s)其實(shí)可以不用。
你可以自己調(diào)試一下。