相信很多人都使用過飛鴿傳書,這個小工具在區域網傳輸資料高效而便捷,自己在大二的時候就想看看飛鴿傳書的原始碼,但那時候自己的水平有限,這幾天有機會重寫飛鴿傳書,也對ipmsg的網路協議做了深入的研究,這裡也要感謝ipmsg的作者公開源**。
ipmsg可以用於收發訊息和檔案(夾)
使用udp協議收發訊息使用tcp協議收發檔案(夾)
預設使用2425埠做資料傳輸(tcp/udp)
包含以下功能
使用者上下線識別
訊息收發
檔案傳輸資料夾傳輸
ipmsg的報文格式:版本號:包編號:傳送者姓名:傳送者主機名:命令字:附加資訊
整個報文通過字串的形式傳送,ipmsg的版本號為1,而包編號必須是不重複的數字,這裡可以是用比較簡潔的方式,就是通過linux的庫函式timer來完成,time 函式返回從1970 年1 月1 日0 點以來的秒數.所以每個執行timer()的結果都是不一樣的,可以放心使用。報文中的命令字是指明這個報文是訊息、上線通告、傳輸檔案、傳輸資料夾還是其他的東西,附加資訊在不同的命令字下是不一樣的,如果命令字是訊息,那麼附加資訊就是訊息內容,如果命令字是傳輸檔案,那麼附加資訊就是檔案的資訊了,我們來看一下命令字,這是ipmsg最為重要的內容。
#ifndef ipmsg_h
#define ipmsg_h
/* ip messenger communication protocol version 1.0 define */
/* macro */
#define get_mode(command)
(command & 0x000000fful)
#define get_opt(command)
(command & 0xffffff00ul)
/* header */
#define ipmsg_version 0x0001
#define ipmsg_default_port 0x0979
/* command */
#define ipmsg_nooperation 0x00000000ul
#define ipmsg_br_entry 0x00000001ul
#define ipmsg_br_exit 0x00000002ul
#define ipmsg_ansentry 0x00000003ul
#define ipmsg_br_absence 0x00000004ul
#define ipmsg_br_isgetlist 0x00000010ul
#define ipmsg_okgetlist 0x00000011ul
#define ipmsg_getlist 0x00000012ul
#define ipmsg_anslist 0x00000013ul
#define ipmsg_file_mtime 0x00000014ul
#define ipmsg_file_createtime 0x00000016ul
#define ipmsg_br_isgetlist2 0x00000018ul
#define ipmsg_sendmsg 0x00000020ul
#define ipmsg_recvmsg 0x00000021ul
#define ipmsg_readmsg 0x00000030ul
#define ipmsg_delmsg 0x00000031ul
/* option for all command */
#define ipmsg_absenceopt 0x00000100ul
#define ipmsg_serveropt 0x00000200ul
#define ipmsg_dialupopt 0x00010000ul
#define ipmsg_fileattachopt 0x00200000ul
/* file types for fileattach command */
#define ipmsg_file_regular 0x00000001ul
#define ipmsg_file_dir 0x00000002ul
#define ipmsg_listget_timer 0x0104
#define ipmsg_listgetretry_timer 0x0105
#define hs_tools "hstools"
#define ip_msg "ipmsg"
#define no_name "no_name"
#define url_str "://"
#define mailto_str "mailto:"
#endif
/* ipmsg_h */
ipmsg_nooperation,預設是不做任何處理,然後上線通告報文
ipmsg_br_entry 。
使用者列表通過鍊錶來實現,看看結構體:
typedef
struct use_date
ipmsg_use;
每次ipmsg在收到上線通告報文後,都要查詢相同ip的節點是否已經存在,只要和結構體成員host_ip比較就可以了,這樣整個使用者列表當中的成員是不會重複的。報文的傳送主要依靠下邊的函式實現,這裡推薦下邊的這種寫法,特別是對與命令比較多的情況下,使用下邊的好處就在與結構非常的清晰。
mode: 命令 msg: 附加資訊 struct
sockaddr
*p:網路資訊 fd:網路套接字描述符
int msg_send(
const
int mode,
const
char
*msg,
const
struct
sockaddr
*p,int fd)
elseif(
(p!=null)&&
(mode!=ipmsg_nooperation)&&
(mode!=ipmsg_br_entry)&&
(mode!=ipmsg_br_exit)
)client=
*p;
//開啟廣播if(
setsockopt
(udp_fd,sol_socket,so_broadcast,
&broadcast_en,broadcast_len)
<0 )
switch
(mode)
broadcast_en=0;
// 關掉廣播if(
setsockopt
(udp_fd,sol_socket,so_broadcast,
&broadcast_en,broadcast_len)
<0 )
printf
("msg send ok ! /n");
return 0;
}
通過上邊的報文就可以實現訊息的傳遞,可以發起檔案、資料夾的傳輸,傳輸檔案時,首先需要通過udp報文聯絡,在udp報文聯絡好之後,隨即發起tcp檔案傳輸,檔案傳輸是不帶格式的。ipmsg的乙個難點就是資料夾的傳輸。今天就寫這裡,而且也做到這裡。
IPMSG 飛鴿傳書 協議翻譯
最近看到一些朋友在編寫網路程式是遇到一些問題,故把以前做ipmsg時翻譯的文件貼過來,希望對網路程式設計新手有所幫助,在尋找程式設計專案的同學們也可參照此文件寫出自己的ipmsg。本文只包含其中幾個比較重要的命令以及執行機制的中文翻譯,更詳細的內容請參照文後的ipmsg 協議英文文件 宣告 下述協議...
IPMSG飛鴿傳書3 協議翻譯
最近看到一些朋友在編寫網路程式是遇到一些問題,故把以前做ipmsg時翻譯的文件貼過來,希望對網路程式設計新手有所幫助,在尋找程式設計專案的同學們也可參照此文件寫出自己的ipmsg。本文只包含其中幾個比較重要的命令以及執行機制的中文翻譯,更詳細的內容請參照文後的ipmsg 協議英文文件 宣告 下述協議...
IPMSG飛鴿傳書5 網路協議解析手記2
每次ipmsg在收到上線通告報文後,都要查詢相同ip的節點是否已經存在,只要和結構 體成員host ip比較就可以了,這樣整個使用者列表當中的成員是不會重複的。報文的傳送主要依靠下邊的函式實現,這裡推薦下邊的這種寫法,特別是對與命 令比較多的情況下,使用下邊的好處就在與結構非常的清晰。mode 命令...