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

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

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

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

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

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

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

6、處理函數(shù)創(chuàng)建socket,綁定端口初始化已用戶鏈表命令服務器端程序啟動客戶端程序啟動User_link.h:該文件定義了用戶鏈表的#define NO_USER_ONLINE 1#define NO_USER_REGISTER 1結構,在前面已提及,同時定義了消息種類:#define NOT_ONLINE #define NOT_REGISTER #define NO_SUCH_USER#define NO_SUCH_USER2233Tcpexample.h:其中定義了與 tcp 傳輸有關的端口信息,堆棧大小等#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同時定義了傳輸消息的結構體struct request int reply;int msgLen;/* TRUE = request reply from server */* length of message text */* message buffer */char messageREQUEST_MSG_SIZE;Tcpserver.h:其中定義了用戶信息保存地址和離線消息地址,同時對 tcpserve

9、r.cpp中的函數(shù)進行。#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:”,否則無法正確進行文件操作。需

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

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

12、ATUS tcpserver (void);struct sockaddr_inserverAddr;/服務器地址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 任務號/用戶鏈表頭表指針用戶鏈表尾指針用戶人數(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)絡地址族serverAddr.sin_port = htons (SERVER_PORT_NU

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

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

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

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

18、 0,表示命令正確,該用戶向另一信息,該函數(shù)將從 requestMessage 中提取出要的信息和接收用戶名,分別保存在 messageSend 和 userName 中;如果返回為 1,表示該用戶準備離線,接下來將調用 userLogout()函數(shù);如果返回為 6,表示該用戶想獲得當前用戶的,接下來將調用 showOnlineUsers()函數(shù);其他幾種返回結果表示命令不正確。 */對消息進行處理的函數(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;/客戶端是否已連接上服務器的信號燈SEM_ID semShutdown; /關閉客戶端信號燈SEM_ID semShowInsturction;/* semLog 初始值為 0,需要/當接收完服務器消息后才開始下一次輸入兩次才能使都阻塞在

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

21、Instruction 為互斥信號量,semLog 為一般信號量,所以它們的取值范圍是不一樣的。*/* 開啟四個任務*/ 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);其它進程會等待netlog()他三個進程進行信號量,于是neglog首先進行,只有當用戶正常登錄時才會有其Neglog首先進行本地socket初始化,與服務器端基本相同,不同的是客戶端需要主動運行connect()連接服務器。其他函數(shù):void tcpClientOfflineTask(int sFd);void netShutdown()int checkValid(char* command);(3) 程序調試/處理離線消息/關閉客戶端/檢查用戶輸入命令的可以在一臺電腦上運行多個 tornado 來模擬通信,因為一個 sim 只能運行一個 debug。編譯完成后會產(chǎn)生鏡像*.o 文件,需要到 Vxsim 中進行調試。1、開啟了三個模擬器2、服務器端運行3、客戶端正常運行4、客戶端登陸5、服務器端處理客戶登陸信息6、用戶 linjay 向 zx消息,zx 不7、zx 登陸并受到離線消息8、zx 向 linjay消息9、linjay 收到來自 zx 的消息10、服務器對消息的

溫馨提示

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

評論

0/150

提交評論