Linux 下飛鴿傳書設(shè)計實(shí)現(xiàn)
1.系統(tǒng)功能
根據(jù)飛鴿傳書協(xié)議在 linux 下實(shí)現(xiàn)飛鴿傳輸程序,并且與 windows 下飛鴿兼容。具體功能模塊包括用戶上線,下線,刷新查看在線用戶,收發(fā)消息,傳送文件/文件夾功能模塊。
2.具體實(shí)現(xiàn)
2.1 關(guān)鍵數(shù)據(jù)結(jié)構(gòu)
/*命令的結(jié)構(gòu)*/
typedef struct _command
{
int version;/*命令的版本*/
int seq;/*包編號*/
char
srcName[100];/*發(fā)送者姓名*/
char
srcHost[100];/*發(fā)送者主機(jī)名*/
int flag;/*命令*/
char
addtion[100];/*附加字段*/
}command;
/*在線用戶信息*/
typedef struct _userInfo
{
char
name[MAXLINE]; /*姓名*/
char
host[MAXLINE]; /*主機(jī)名*/
char
group[MAXLINE]; /*所在的組名*/
struct
sockaddr_in addr; /*地址信息*/
struct
_userInfo next; /*鏈表中下一個*/
}userInfo;
/*在線用戶列表*/
typedef struct _uList
{
userInfo
*userListHead; /*鏈表頭*/
userInfo
userListTail; /*鏈表尾*/
}uList;
/*消息隊列*/
typedef struct _mesList
{
command
*mesHead;
command
*mesTail;
}mesList;
2.2 程序主要結(jié)構(gòu)
本程序主要采用多線程結(jié)構(gòu),分為 receive(接收消息), process(處理收到的消息), sendData(發(fā)送文件) 三個子線程。線程間通信互斥鎖與 Posix 信號量進(jìn)行通信。
2.3 函數(shù)接口
(1) /*從文件描述符fd中讀取count個字符存入buf中*/
ssize_t
readn(int fd,void *buf,size_t count);
(2) /*將buf所指向的存儲區(qū)中的len個字符吸入文件描述符fd中*/
ssize_t
writen(int fd,char *buf,int len);
(3) /*用于字符串轉(zhuǎn)換,網(wǎng)絡(luò)傳輸中用gb2312編碼,linux下gtk用utf-8編碼,需要進(jìn)行轉(zhuǎn)換*/
int
code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char
*outbuf,int outlen);
(4) /*在用戶鏈表中加入新用戶信息,加入成功返回1,否則返回0,使用userInfoMutex進(jìn)行線程間通信控制*/
int
pushBack(uList *list,userInfo user);
(5) /*在用戶鏈表中刪除指定地址信息的用戶,刪除成功后返回1,否則返回0,使用userInfoMutex進(jìn)行線程間控制*/
int
delUser(uList *list, struct sockaddr_in addr);
(6) /*判斷該用戶是否已經(jīng)存在,已經(jīng)存在則返回1,否則返回0,使用userInfoMutex進(jìn)行線程間控制*/
int isExist(uList *list,struct sockaddr_in addr);
(7)清空用戶鏈表,釋放空間,用于用戶退出和用戶刷新時釋放空間,使用userInfoMutex進(jìn)行線程間控制*/
int destroyList(uList *list);
(8)/*創(chuàng)建命令字,com為要返回的命令字,flag 為消息標(biāo)志,addtion 為附加標(biāo)志*/
void createCmd(command & com,int flag,char
addtion[])
(9)/*發(fā)送消息,com為要發(fā)送的消息,servaddr為要發(fā)送的地址,attach為文件附件信息*/
void sendCmd(command com, struct sockaddr_in
servaddr,char attach[]);
(10) /*把收到的消息加入到消息隊列中*/
void addMes(mesList *mHead,command cmd);
(11) /*把消息隊列中頭部的節(jié)點(diǎn)消息提取出來用于處理*/
int delMes(mesList *mHead,command *cmd);
(12)/*初始化操作,飛鴿登錄時初始化消息鏈表,用戶鏈表,信號量,套接字信息*/
void init();
(13)/*登錄操作,發(fā)送用戶上線消息*/
void login();
(14)/*解析收到的消息命令,提取各個字段*/
int
analysisCmd(command *cmd,char *buf);
(15) /*接收消息線程處理函數(shù),將收到的消息加入消息隊列中,通過信號量waitNoFull和waitNoEmpty和消息處理線程進(jìn)行通信。消息隊列用mesMutex與其他線程進(jìn)行通信,保證消息隊列的正確性*/
void
*receive(void *arg);
(16)/*gtk界面中顯示在線用戶信息*/
void showUser(uList *list);
(17)/*在gtk界面中顯示消息*/
void showMessage(char *message);
(18)/*顯示收到的信息*/
void showRecvMessage(char *host,char *message);
(19)/*分析文件的信息,提取有用的字段*/
void fileAnalysis(char *recv,int *fNum,char *fName,int
*fSize,int *fTime,int *fType);
(20) /*保存收到的單個文件,saveName為保存的文件名*/
void saveSignalFile(char *saveName);
(21)/*分析目錄附件,獲得目錄文件的文件名,文件大小,文件類型*/
void getDirInfo(char *recv,char *fName,int *fSize,int
*fType);
(22) /*保存目錄,saveName為要保存的目錄*/
void saveDir(char *saveName);
(23)/*保存文件,recvType=1為保存文件,recvType=2為保存的目錄,使用fileMutex來設(shè)置互斥性*/
void saveFile();
(24)/*收到單個文件*/
void receiveSignalFile(char *recvFileName);
(25)/*收到單個目錄*/
void receiveDir(char *recvDirName);
(26)/*接收文件*/
void receiveFile(command cmd);
(27)/*信號處理線程,從消息隊列中取出消息進(jìn)行處理*/
void *process(void *arg);
(28)/*發(fā)送消息*/
int sendMes();
(29) /*將文件名進(jìn)行轉(zhuǎn)換*/
char *transName(char *fileName);
(30)/*發(fā)送文件*/
void sendFile();
(31)/*發(fā)送文件夾*/
void sendDir();
(32)/*用戶點(diǎn)擊刷新,刷新在線用戶*/
void refresh();
(33) /*用戶退出*/
void quit();
(34)/*傳輸文件夾數(shù)據(jù),遞歸函數(shù)*/
void transferDir(int fd,char *dir);
(35)/*監(jiān)聽TCP套接口,發(fā)送文件與文件夾線程*/
void *sendData(void *arg);
(36)/*創(chuàng)建菜單*/
static void create_popup_menu(GtkWidget
*menu,GtkWidget *view);
(37)/*右擊選中treeview,顯示傳送文件與文件夾菜單*/
static gboolean showTreeView(GtkWidget
*eventBox,GdkEventButton *event,GtkWidget *menu);
(38)/*選擇要發(fā)送的文件 */
static void selectFile();
(39)/*選擇要發(fā)送的文件夾*/
static void selectDir();
(40)/*選擇要保存的文件名或文件夾名*/
static void selectSaveFile();
3.總結(jié)
實(shí)現(xiàn)了linux下飛鴿傳書的基本功能,并且能與window下飛鴿進(jìn)行通信,傳文件。熟悉了linux下網(wǎng)絡(luò)編程,多線程編程及線程間通信(主要用到信號量與互斥鎖)。但加密解密那塊沒有完成,程序結(jié)構(gòu)不是很好,界面做得太差。有空應(yīng)該看看設(shè)計模式.
界面截圖(界面比較垃圾):

附:
飛鴿協(xié)議: http://bbs.chinaunix.net/viewthread.php?tid=1015775