丁高強(qiáng)大三下作業(yè)u_第1頁
丁高強(qiáng)大三下作業(yè)u_第2頁
丁高強(qiáng)大三下作業(yè)u_第3頁
丁高強(qiáng)大三下作業(yè)u_第4頁
免費(fèi)預(yù)覽已結(jié)束,剩余8頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、軟件課程設(shè)計(jì)實(shí)驗(yàn)報(bào)告題:基于 Vxworks 的聊天程序的設(shè)計(jì)課班級(jí):通信工程 0705作者:汪濱學(xué)號(hào):u200713590: 王德勝指導(dǎo)課設(shè)評(píng)價(jià):課設(shè)成績(jī):一項(xiàng)目描述本次課程設(shè)計(jì)是編寫一個(gè)基于 Vxworks 系統(tǒng)的類似于的聊天工具,通過程序編寫,使同學(xué)們了解 Vxworks 的編程環(huán)境,加深對(duì)網(wǎng)絡(luò)協(xié)議的理解。二系統(tǒng)描述本程序采用 c 語言編寫,分為服務(wù)器和客戶端兩個(gè)部分。當(dāng)用戶向其他用戶信息時(shí),必須經(jīng)過服務(wù)器端的中轉(zhuǎn),獲得目標(biāo)用戶信息以決定對(duì)消息作、或者得到目標(biāo)用戶不存在的情況。服務(wù)器端依靠鏈表維持所有在線和已用戶的信息。已登陸用戶可以向用戶即時(shí)消息,也可以向離線用戶離線消息。對(duì)于離線消息

2、,服務(wù)器端為每一個(gè)有離線消息的賬號(hào)創(chuàng)建一個(gè) txt 文檔,將信息保存起來,當(dāng)此用戶登陸時(shí),服務(wù)器將離線消息給他,并將 txt 文檔刪除。三數(shù)據(jù)結(jié)構(gòu)已用戶結(jié)構(gòu)體為:typedef struct registerInfochar username30; char usercipher20;/已用戶結(jié)構(gòu)體struct registerInfo* next;REGISTERINFO;其中,字符串 username 用來保存賬號(hào)名稱,usercipher 用來保存用戶用戶結(jié)構(gòu)體為:。typedef struct userInfo/char username30; char userIP20; int s

3、Fd;struct userInfo* next;USERINFO;其中,字符創(chuàng) userIP 用來保存用戶結(jié)構(gòu)體用于所用客戶端的 IP 地址,整型變量 sFd 保存服務(wù)器為此賬號(hào)的 TCP 連接分配的套接字號(hào)四軟件設(shè)計(jì)為了實(shí)現(xiàn)離線傳輸?shù)裙δ?,采用一個(gè)公共服務(wù)器的設(shè)計(jì)。服務(wù)器端和客戶端是設(shè)計(jì)的,它們對(duì)信息的處理是的,只依靠 TCP/IP 傳連接中是否有信息流,輸協(xié)議傳輸消息。當(dāng)連接建立后,服務(wù)器和客戶端都不停的一旦收到信息,則由消息函數(shù)確定下一步的操作。sockLib.h 中 write(), fioRead()函數(shù)分別完成對(duì) TCP 連接中的數(shù)據(jù)流的寫與讀的操作。為了使兩端協(xié)同工作,對(duì)于兩者

4、之間傳輸?shù)男畔⒌母袷奖仨氝M(jìn)行設(shè)計(jì)以實(shí)現(xiàn)不同的功能。在本軟件中,規(guī)定:1) 用戶登陸命令的格式為:L+空格+用戶名+空格+;(也可用小寫的 l);(也可用小寫的 r)2) 用戶命令的格式為:R+空格+用戶名+空格+3) 用戶向另一用戶消息令的格式為:t+接受用戶名+空格+消息;4) 用戶用戶名稱命令格式為:show+空格+users;5) 用戶關(guān)閉客戶端令格式為:shut+空格+down;在客戶端,系統(tǒng)會(huì)調(diào)用函數(shù)先將用戶輸入令進(jìn)行檢錯(cuò),只有為合法令,客戶端才會(huì)將命令給服務(wù)器。五程序流程用戶命令輸入否是否正確是是shut down?否解除阻塞刪除Task(n) 詳細(xì)框圖結(jié)束是是否否接收用戶在線?正

5、確?shut down?show users?是否是否六技術(shù)報(bào)告由于采用客戶/服務(wù)器模式,本程序主要有兩個(gè)部分可,tcpserver.cpp 實(shí)現(xiàn)服務(wù)器端功能,tcpclient.cpp 實(shí)現(xiàn)客戶端功能。頭文件 user_link.h 定義了兩個(gè)鏈表的結(jié)構(gòu)和操作,tcpExample.h 定義了 TCP/IP 協(xié)議中的一些主要參數(shù),tcpServer.h 和 tcpClient.h分別定義了兩端的(1) 頭文件設(shè)計(jì)。保存離線文件Task(n)結(jié)束將用戶發(fā)送給用戶反饋給用戶信息即時(shí)消息給接收用戶用戶請(qǐng)求信息接收信息任務(wù)關(guān)閉客戶端任務(wù)信息任務(wù)Task(n)用戶(n)連接請(qǐng)求到新的連接后分配套接字和

6、處理函數(shù)創(chuàng)建socket,綁定端口初始化已用戶鏈表命令服務(wù)器端程序啟動(dòng)客戶端程序啟動(dòng)User_link.h:該文件定義了用戶鏈表的#define NO_USER_ONLINE 1#define NO_USER_REGISTER 1結(jié)構(gòu),在前面已提及,同時(shí)定義了消息種類:#define NOT_ONLINE #define NOT_REGISTER #define NO_SUCH_USER#define NO_SUCH_USER2233Tcpexample.h:其中定義了與 tcp 傳輸有關(guān)的端口信息,堆棧大小等#define SERVER_PORT_NUM #define CLIENT_POR

7、T_NUM #define SERVER_WORK_PRIORITY#define SERVER_STACK_SIZE#define USER_STACK_SIZE500150021001000010000/* servers port number for bind() */* priority of servers work task */* stack size of servers work task */#define SERVER_MAX_CONNECTIONS 4/* max clients connected at a time */* max size of request

8、message */* max size of reply message */#define REQUEST_MSG_SIZE#define REPLY_MSG_SIZE1024500同時(shí)定義了傳輸消息的結(jié)構(gòu)體struct request int reply;int msgLen;/* TRUE = request reply from server */* length of message text */* message buffer */char messageREQUEST_MSG_SIZE;Tcpserver.h:其中定義了用戶信息保存地址和離線消息地址,同時(shí)對(duì) tcpserve

9、r.cpp中的函數(shù)進(jìn)行。#define PATH_ONLINE_USERhost:e:Tornado2.2data_useronline_user.txt/用戶初始化的文本文件路徑#define PATH_REGISTER_USER host:e:Tornado2.2data_userregister_user.txt/ 已用戶初始化的文本文件路徑#define PATH_MESSAGE_TO_SEND host:e:Tornado2.2data_usermessageToSend/ 離線消息保存路徑/*注意此處,Vxworks 中文件的路徑名前要加”host:”,否則無法正確進(jìn)行文件操作。需

10、要使用轉(zhuǎn)移符“/”來得到“/”*/Tcpclient.h:其中定義了為保持客戶端進(jìn)程有序運(yùn)行而使用的信號(hào)量SEM_ID semLog;/客戶端是否已連接上服務(wù)器的信號(hào)燈SEM_ID semShutdown; /關(guān)閉客戶端信號(hào)燈SEM_ID semShowInsturction;/當(dāng)接收完服務(wù)器消息后才開始下一次輸入同時(shí)定義了各個(gè)任務(wù)的優(yōu)先級(jí)#define TPRI_SHUTDOWN #define TPRI_NETLOG #define TPRI_NETCOMM151152153/任務(wù)優(yōu)先級(jí)#define TPRI_NETLISTEN/任務(wù)優(yōu)先級(jí)最好在 120 以下(2) 函數(shù)主體設(shè)計(jì)Tcps

11、erver.cpp:154通過查閱資料,我了解了 socket 編程的基礎(chǔ)知識(shí):進(jìn)行網(wǎng)絡(luò)通信前必須先通過申請(qǐng) socket 建立連接的端點(diǎn),網(wǎng)間網(wǎng)內(nèi)部,一個(gè) socket用一個(gè)半相關(guān)描述即:(協(xié)議,本地地址,本地端口)通信時(shí),服務(wù)器端首先通過 socket()獲取套接字文件描述符,然后用 bind()綁定網(wǎng)絡(luò)地址,調(diào)用 listen()進(jìn)行,accept()在客戶段通過 connect()連接時(shí)返回一個(gè)新的套接字文件描述符用于跟客戶端通信。經(jīng)過一系列 read() write()通信后,調(diào)用 close()關(guān)閉連接。Tcp 傳輸中所用的地址信息由結(jié)構(gòu) sockaddr_in 表示。函數(shù)為:ST

12、ATUS tcpserver (void);struct sockaddr_inserverAddr;/服務(wù)器地址struct sockaddr_inclientAddr; /用戶地址int int int int charUSERINFO* USERINFO*int n1 = 0;sockAddrSize; sFd;newFd;ix = 0; workName16;head1 = NULL;rear1 = NULL;/連接新用戶的 SOCKET/用于綁定的 SOCKET/ TCP 任務(wù)號(hào)/用戶鏈表頭表指針用戶鏈表尾指針用戶人數(shù)啟動(dòng)服務(wù)器時(shí)需要初始化鏈表:void userInfoCreate

13、(USERINFO* head, USERINFO*rear, char* userName, char* userIP, int *n, int sFd);本地地址建立:sockAddrSize = sizeof (struct sockaddr_in);bzero (char *) &serverAddr, sockAddrSize); serverAddr.sin_family = AF_INET; serverAddr.sin_len = (u_char) sockAddrSize;/清空/網(wǎng)絡(luò)地址族serverAddr.sin_port = htons (SERVER_PORT_NU

14、M);serverAddr.sin_addr.s_addr = htonl (INADDR_ANY);/主機(jī)到網(wǎng)絡(luò)的字節(jié)順序轉(zhuǎn)換在創(chuàng)建 socket,bind 建立完畢后,開始(taskSpawn (workName,,每當(dāng)?shù)絹碜钥蛻舳说恼?qǐng)求,便調(diào)用 taskspawn/ 任務(wù)名/任務(wù)優(yōu)先級(jí)SERVER_WORK_PRIORITY,0, SERVER_STACK_SIZE,(FUNCPTR) tcpServerWorkTask, newFd,(int) inet_ntoa (clientAddr.sin_addr),/ntohs (clientAddr.sin_port),/ 任務(wù)可用堆棧大小

15、/ 調(diào)用函數(shù)句柄/ 分配的套接字用戶的 IP 地址強(qiáng)行轉(zhuǎn)換為 integer 類型用戶的端強(qiáng)行轉(zhuǎn)換為 integer 類型(int) &head1,(int) &rear1,(int) &n1, (int) &head2,(int) &rear2,(int) &n2, 0);/*特別注意 VXworks 中開啟新任務(wù)的方法,taskSpawn 函數(shù)有 15 個(gè)參數(shù),其中前5 個(gè)確定了要調(diào)用任務(wù)的函數(shù),而后面的 9 個(gè)參數(shù)為函數(shù)的參數(shù),最后一個(gè) 0 為尚未用到的參數(shù)位置。每個(gè)參數(shù)都需要將類型強(qiáng)行轉(zhuǎn)換為整形類。*/)為此 tcp 連接創(chuàng)建進(jìn)程 tTcpworkN,進(jìn)程在 tcpServerWork

16、Task。VOID tcpServerWorkTask (int sFd,char * address, u_short port, USERINFO* head1, USERINFO* rear1, int* n1,REGISTERINFO* head2, REGISTERINFO* rear2, int* n2);/ 服務(wù)器分配給此連接的套接字/ 用戶的 IP/ 用戶的端/ 指向/ 指向/ 指向/ 指向已/ 指向已/ 指向已用戶鏈表的表頭指針的指針用戶鏈表的表尾指針的指針用戶鏈表表長(zhǎng)的指針用戶鏈表的表頭指針的指針用戶鏈表的表尾指針的指針用戶鏈表表長(zhǎng)的指針此進(jìn)程調(diào)用 tcpTackleMes

17、sage 實(shí)現(xiàn)對(duì)消息的以返回結(jié)果進(jìn)行處理int tcpTackleMessage (char * requestMessage, char* userName,char* messageSend,/ 用戶的請(qǐng)求信息/ 接收信息的用戶的用戶名/ 要傳送的信息USERINFO*head1,USERINFO*rear1,int*n1,REGISTERINFO*head2,REGISTERINFO* rear2, int* n2, char* address,int sFd);方用戶完整命令包含在字符串 requestMessage 中,此函數(shù)對(duì)其進(jìn)行/*,判斷用戶。一共有 7 中返回結(jié)果,如果返回為

18、 0,表示命令正確,該用戶向另一信息,該函數(shù)將從 requestMessage 中提取出要的信息和接收用戶名,分別保存在 messageSend 和 userName 中;如果返回為 1,表示該用戶準(zhǔn)備離線,接下來將調(diào)用 userLogout()函數(shù);如果返回為 6,表示該用戶想獲得當(dāng)前用戶的,接下來將調(diào)用 showOnlineUsers()函數(shù);其他幾種返回結(jié)果表示命令不正確。 */對(duì)消息進(jìn)行處理的函數(shù):int tcpSendMessage(char* receiverIp, char* senderName,char* messageSend);/消息函數(shù)void tcpSaveOffli

19、neMessage(char* receiverName, char* senderName, char* messageSend); /保存離線消息void tcpCheckOfflineMessage(int sFd, char* userName,char* replyMsg);/檢查是否有離線消息Tcpclient.cpp:SEM_ID semLog;/客戶端是否已連接上服務(wù)器的信號(hào)燈SEM_ID semShutdown; /關(guān)閉客戶端信號(hào)燈SEM_ID semShowInsturction;/* semLog 初始值為 0,需要/當(dāng)接收完服務(wù)器消息后才開始下一次輸入兩次才能使都阻塞在

20、其上的消息接收和消息任它,務(wù)運(yùn)行。semShutdown 初始值為 0,當(dāng)用戶輸入”shut down”時(shí)或出錯(cuò)時(shí),關(guān)閉客戶端任務(wù)為最高優(yōu)先級(jí),其關(guān)閉其他 3 個(gè)任務(wù),通過與優(yōu)先級(jí)的配合,保證客戶端進(jìn)程正常工作 */semLog = semCCreate(SEM_Q_PRIORITY,0);/創(chuàng)建信號(hào)燈semShutdown = semBCreate(SEM_Q_PRIORITY,SEM_EMPTY); semShowInsturction = semBCreate(SEM_Q_PRIORITY,SEM_FULL);/* 幾個(gè)信號(hào)量的類型不是完全相同的,semShutdown, semShow

21、Instruction 為互斥信號(hào)量,semLog 為一般信號(hào)量,所以它們的取值范圍是不一樣的。*/* 開啟四個(gè)任務(wù)*/ taskSpawn(TNAME_SHUTDOWN,TPRI_SHUTDOWN,0,USER_STACK_SIZE,(FUNCPTR)netShutdown,0,0,0,0,0,0,0,0,0,0); taskSpawn(TNAME_NETLOG,TPRI_NETLOG,0,USER_STACK_SIZE,(FUNCPTR)netLog,0,0,0,0,0,0,0,0,0,0); taskSpawn(TNAME_NETCOMM,TPRI_NETLOG,0,USER_STACK

22、_SIZE,(FUNCPTR)netComm,0,0,0,0,0,0,0,0,0,0); taskSpawn(TNAME_NETLISTEN,TPRI_NETLISTEN,0,USER_STACK_SIZE,(FUNCPTR)netListen,0,0,0,0,0,0,0,0,0,0);其它進(jìn)程會(huì)等待netlog()他三個(gè)進(jìn)程進(jìn)行信號(hào)量,于是neglog首先進(jìn)行,只有當(dāng)用戶正常登錄時(shí)才會(huì)有其Neglog首先進(jìn)行本地socket初始化,與服務(wù)器端基本相同,不同的是客戶端需要主動(dòng)運(yùn)行connect()連接服務(wù)器。其他函數(shù):void tcpClientOfflineTask(int sFd);void netShutdown()int checkValid(char* command);(3) 程序調(diào)試/處理離線消息/關(guān)閉客戶端/檢查用戶輸入命令的可以在一臺(tái)電腦上運(yùn)行多個(gè) tornado 來模擬通信,因?yàn)橐粋€(gè) sim 只能運(yùn)行一個(gè) debug。編譯完成后會(huì)產(chǎn)生鏡像*.o 文件,需要到 Vxsim 中進(jìn)行調(diào)試。1、開啟了三個(gè)模擬器2、服務(wù)器端運(yùn)行3、客戶端正常運(yùn)行4、客戶端登陸5、服務(wù)器端處理客戶登陸信息6、用戶 linjay 向 zx消息,zx 不7、zx 登陸并受到離線消息8、zx 向 linjay消息9、linjay 收到來自 zx 的消息10、服務(wù)器對(duì)消息的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論