《綜合課程設(shè)計(jì)》設(shè)計(jì)報(bào)告基于Socket的即時(shí)通訊系統(tǒng)_第1頁(yè)
《綜合課程設(shè)計(jì)》設(shè)計(jì)報(bào)告基于Socket的即時(shí)通訊系統(tǒng)_第2頁(yè)
《綜合課程設(shè)計(jì)》設(shè)計(jì)報(bào)告基于Socket的即時(shí)通訊系統(tǒng)_第3頁(yè)
《綜合課程設(shè)計(jì)》設(shè)計(jì)報(bào)告基于Socket的即時(shí)通訊系統(tǒng)_第4頁(yè)
《綜合課程設(shè)計(jì)》設(shè)計(jì)報(bào)告基于Socket的即時(shí)通訊系統(tǒng)_第5頁(yè)
已閱讀5頁(yè),還剩14頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、評(píng)閱教師評(píng)語:課程設(shè)計(jì)成績(jī)考勤成績(jī)實(shí)做成績(jī)報(bào)告成績(jī)總評(píng)成績(jī)指導(dǎo)教師簽名:綜合課程設(shè)計(jì)設(shè) 計(jì) 報(bào) 告論文題目: 基于socket的即時(shí)通訊系統(tǒng) 學(xué)院(系): 電子信息與自動(dòng)化學(xué)院 班 級(jí): 721 學(xué)生姓名: 學(xué)號(hào) 指導(dǎo)教師: 時(shí)間: 2011 年 6月 7日 到 2011 年 6 月 17日一、 設(shè)計(jì)目的通過綜合課程設(shè)計(jì),使學(xué)生能夠運(yùn)用數(shù)字信號(hào)處理、信號(hào)與系統(tǒng)、通信原理、面向?qū)ο蟮某绦蛟O(shè)計(jì)、計(jì)算機(jī)通信網(wǎng)、通信協(xié)議開發(fā)及應(yīng)用等課程的知識(shí)來設(shè)計(jì)一個(gè)基于socket的即時(shí)通訊系統(tǒng),培養(yǎng)學(xué)生的動(dòng)手能力以及分析問題、解決問題的能力。二、 設(shè)計(jì)內(nèi)容一個(gè)基于socket的即時(shí)通訊系統(tǒng)的多人聊天軟件三、 設(shè)計(jì)

2、要求(一)基本要求1 熟練掌握面向?qū)ο蟮某绦蛟O(shè)計(jì)方法;2 實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)通訊,能進(jìn)行文字對(duì)話傳輸,包括客戶端與服務(wù)器端;3 能對(duì)系統(tǒng)參數(shù)進(jìn)行配置。(二)提高要求1、實(shí)現(xiàn)文件、圖片傳輸;2、語音對(duì)話(兩人及兩人以上);3、友好的對(duì)話界面。四、 設(shè)計(jì)原理1 tcp/ip簡(jiǎn)介 tcp/ip的歷史要追溯到70年代中期,當(dāng)時(shí)arpa為了實(shí)現(xiàn)異種網(wǎng)之間的互連(interconnection)與互通(intercommunication),大力資助網(wǎng)間網(wǎng)技術(shù)的研究和開發(fā),于1977年到1979年推出目前形式的tcp/ip體系結(jié)構(gòu)和協(xié)議規(guī)范.到今天,tcp/ip技術(shù)以及internet網(wǎng)間網(wǎng)已經(jīng)為廣大計(jì)算機(jī)工作者

3、,機(jī)算機(jī)廠商和機(jī)算機(jī)用戶所接受.據(jù)統(tǒng)計(jì),到1990年,internet以包含遍布?xì)W美的五千個(gè)活動(dòng)網(wǎng)絡(luò),超過三十萬臺(tái)機(jī)算機(jī).作為一種事實(shí)上的工標(biāo)準(zhǔn),tcp/ip技術(shù)方興未艾.2 tcp/ip的網(wǎng)絡(luò)分層結(jié)構(gòu) 對(duì)tcp/ip協(xié)議來說,tcp提供傳輸層服務(wù),ip提供網(wǎng)絡(luò)層服務(wù).tcp/ip協(xié)議組(或internet協(xié)議組)的分層結(jié)構(gòu)及其與osi模型的對(duì)應(yīng)關(guān)系如圖4所示.圖中有關(guān)協(xié)議的名稱及其基本含義如下: (1) tcp. 為傳輸控制協(xié)議(transmission control protocol).它是提供給用戶進(jìn)程的一個(gè)可靠的全雙工字節(jié)流的面向連接的協(xié)議.大多數(shù)internet應(yīng)用程序使用tcp.

4、因?yàn)閠cp使用ip,所以整個(gè)internet協(xié)議組也常稱為tcp/ip協(xié)議組. (2) udp. 為用戶數(shù)據(jù)報(bào)協(xié)議 (user datagram protocol). (3) icmp. 為網(wǎng)間報(bào)文控制協(xié)議 (internet control message protocol). (4) ip. 網(wǎng)間協(xié)議 (internet protocol). ip協(xié)議是為tcp,udp和icmp提供分組發(fā)送服務(wù)協(xié)議. (5) arp. 地址轉(zhuǎn)換協(xié)議. (6) rarp. 反向地址轉(zhuǎn)換協(xié)議.3 socket編程界面 (1) socket 原理 socket編程界面由4bsd unix首先提出,目的是解決網(wǎng)間

5、網(wǎng)進(jìn)程通信問題.socket接口為進(jìn)程間通信提供了一種新的手段,它不但能用于同一機(jī)器中的進(jìn)程之間的通信,而且支持網(wǎng)絡(luò)通信功能.socket具有類型,反應(yīng)了對(duì)用戶透明的通信特性. 一個(gè)完整的socket連接用一個(gè)相關(guān)描述: 協(xié)議,本地地址,本地端口,遠(yuǎn)地地址,遠(yuǎn)地端口 socket 是面向客戶-服務(wù)器模型而設(shè)計(jì)的,針對(duì)客戶和服務(wù)器程序提供不同的socket系統(tǒng)調(diào)用. (2) socket系統(tǒng)調(diào)用 不管socket內(nèi)部機(jī)制如何,它提供給應(yīng)用程序員的最終界面是一組系統(tǒng)功能調(diào)用.下面,我們一一給出重要的socket系統(tǒng)調(diào)用. 1. 創(chuàng)建 socket - socket() 調(diào)用格式如下: sockid

6、 = socket (af,type,protocol) af : 地址族,指本socket所用地址類型. type : 類型,指創(chuàng)建socket的應(yīng)用程序所希望的通信服務(wù)器類型. protocol : 協(xié)議,指本socket請(qǐng)求的協(xié)議. 2. 指定本地地址 - bind()調(diào)用 bind()將本地socket地址與所創(chuàng)建的socket聯(lián)系起來,即將本socket地址賦予socket,以指定本地半相關(guān).bind()的作用相當(dāng)于給socket命名,調(diào)用格式為: bind (sockid,localaddr,addrlen) sockid : socket號(hào). localaddr : 本地sock

7、et地址. addrlen : 地址長(zhǎng)度. 3. 建立socket連接 - connect () 與 accept ()調(diào)用 這兩個(gè)系統(tǒng)調(diào)用用于完成整個(gè)相關(guān)的建立.其中connect用于建立連接 .調(diào)用格為: connect (sockid,destaddr,addrlen) destaddr : 指向?qū)Ψ絪ocket地址(信宿地址)結(jié)構(gòu)的指針. accept : 用于面向連接的服務(wù)器,其調(diào)用格式為: newsock = accept (sockid,clientaddr,paddrlen) clientaddr : 指向客戶socket地址指針. paddrlen : 客戶socket地址長(zhǎng)

8、度. 4. listen() 調(diào)用 此調(diào)用用于面向連接服務(wù)器,表明它愿意接收連接,listen()在accept()之前調(diào)用,格式為: listen (sockid,quelen) quelen : 請(qǐng)求隊(duì)列長(zhǎng)度. 5. 發(fā)送數(shù)據(jù) - write(),writev(),send()與sendto(),sendmsg() 用于socket數(shù)據(jù)發(fā)送的系統(tǒng)調(diào)用一共有五個(gè),其中三個(gè),write(),writev()和send()用于面向連接傳輸,其余兩個(gè)用于無連接傳輸.面向連接的調(diào)用可以不指定信宿地址,而無連接的調(diào)用必須指定.假如無連接socket的雙方均調(diào)用過connect(),可以認(rèn)為是建立有連接

9、的socket,也可以面向連接調(diào)用發(fā)送數(shù)據(jù). 三個(gè)面向連接調(diào)用三者的格式大致相同: write (sockid,buff,bufflen) : 緩沖發(fā)送 writev (sockid,iovector,vectorlen) : 集中發(fā)送 send (sockid,buff,bufflen,flags) : 可控緩沖發(fā)送 其中buff指向發(fā)送緩沖區(qū)的指針,bufflen是發(fā)送緩沖區(qū)大小. 用于無連接數(shù)據(jù)發(fā)送的調(diào)用有兩個(gè): sendto (sockid,buff,bufflen,flags,dsadd,addrlen) sendmsg (sockid,message,flags):可控集中無連接發(fā)

10、送. 6. 接收數(shù)據(jù) - read(),readv(),recv()與recvfrom(),recvmsg() 接收數(shù)據(jù)與發(fā)送數(shù)據(jù)系統(tǒng)調(diào)用是一一對(duì)應(yīng)的,兩者參數(shù)的最大區(qū)別是,前者buffer是一個(gè)指針,其所指單元初值為欲讀數(shù)據(jù)長(zhǎng)度,調(diào)用后的值是實(shí)際讀出的值.4 客戶-服務(wù)器模型的socket實(shí)現(xiàn)框架 1)客戶-服務(wù)器模型時(shí)序圖 下圖是面向連接客戶-服務(wù)器模型的典型時(shí)序圖 服務(wù)器 客戶 socket() socket() bind() bind() listen() accept() 等待客戶連接請(qǐng)求 阻塞 connect() read() write() 2)服務(wù)器socket地址的確定在客戶

11、-服務(wù)器模型中,所有的作用者都是客戶首先發(fā)起的(如連接請(qǐng)求,服務(wù)請(qǐng)求等),因此客戶必須要知道服務(wù)器socket地址,另外,客戶調(diào)用服務(wù)器之前,可以在命令行中給出服務(wù)器所在主機(jī)的域名,根據(jù)域名可以獲得服務(wù)器主機(jī)的地址,系統(tǒng)調(diào)用為:hp=gethostbyname(host).其中host可以是服務(wù)器主機(jī)域名,返回hp是一個(gè)指向主機(jī)地址結(jié)構(gòu)的指針。五、 軟件設(shè)計(jì)(附程序流程圖、源程序清單)1. 程序流程圖2.源程序清單void cchatroomdlg:dlgallinit()checkradiobutton(idc_radio_client, idc_radio_server, idc_radi

12、o_client);setdlgitemtext(idc_ip_addr, _t(); / 初始化ip地址為本機(jī)地址。setdlgitemtext(idc_connect_port, _t(5566); / 初始化端口。setdlgitemtext(idc_listen_port, _t(5566);enablewindow(idc_stop_client, false);enablewindow(idc_listen_port, false);enablewindow(idc_stop_server, false);enablewindow(idc_start_server

13、, false);enablewindow(idc_static_listen_port, false); / 初始化按鍵啟用or禁用。enablewindow(idc_sendmsg, false);bool cchatroomdlg:enablewindow(uint uid, bool benable)return getdlgitem(uid)-enablewindow(benable);void cchatroomdlg:extenddiaog(bool bshow)static crect m_dlgrectlarge(0, 0, 0, 0);static crect m_dlgr

14、ectsmall(0, 0, 0, 0);static crect m_grouprectlarge(0, 0, 0, 0);static crect m_grouprectsmall(0, 0, 0, 0); / 設(shè)置 窗口大小 if ( m_dlgrectlarge.isrectnull() ) getwindowrect(&m_dlgrectlarge);m_dlgrectsmall = m_dlgrectlarge;m_dlgrectsmall.right -= 220;:getwindowrect(getdlgitem(idc_frame)-getsafehwnd(), &m_gro

15、uprectlarge);m_grouprectsmall = m_grouprectlarge;m_grouprectsmall.right -= 220; / 設(shè)置 窗口 伸縮大小范圍if ( bshow ) bshowall = true;setwindowpos(null, 0, 0, m_dlgrectlarge.width(), m_dlgrectlarge.height(), swp_nozorder | swp_nomove);:setwindowpos(getdlgitem(idc_frame)-getsafehwnd(), null, 0, 0, m_grouprectla

16、rge.width(), m_grouprectlarge.height(), swp_nozorder | swp_nomove);elsebshowall = false;setwindowpos(null, 0, 0, m_dlgrectsmall.width(), m_dlgrectsmall.height(), swp_nozorder | swp_nomove);:setwindowpos(getdlgitem(idc_frame)-getsafehwnd(), null, 0, 0, m_grouprectsmall.width(), m_grouprectsmall.heigh

17、t(), swp_nozorder | swp_nomove);void cchatroomdlg:onbnclickednetset()if ( bshowall ) extenddiaog(false);elseextenddiaog(true); / 設(shè)置按鍵“網(wǎng)絡(luò)設(shè)置”的作用void cchatroomdlg:onbnclickedstartserver()m_hlistenthread = createthread(null, 0, listenthreadfunc, this, 0, null);void cchatroomdlg:showmsg(cstring strmsg)m_

18、msgedit.setsel(-1, -1);m_msgedit.replacesel(strmsg+_t(rn);void cchatroomdlg:removeclientfromarray(cclientitem in_item)for( int idx = 0; idx ) + strmsg;showmsg(strmsg);sendclientsmsg(strmsg);else if (m_bisserver = false) cstring strtmp = _t(張智超的客戶端:) + strmsg;showmsg(strtmp);int isend = send(m_connec

19、tsock, (char *)strmsg.getbuffer(), strmsg.getlength()*sizeof(tchar), 0);strmsg.releasebuffer();elseafxmessagebox(_t(請(qǐng)您先進(jìn)入聊天室!);setdlgitemtext(idc_input_msg, _t(); / socket 基本應(yīng)用void cchatroomdlg:onbnclickedstartclient()m_hconnectthred = createthread(null, 0, connectthreadfunc, this, 0, null);void cch

20、atroomdlg:sendclientsmsg(cstring strmsg, cclientitem *pnotsend)tchar szbufmax_buf_size = 0;_tcscpy_s(szbuf, max_buf_size, strmsg);for( int_ptr idx = 0; idx m_socket != m_clientarray.getat(idx).m_socket | pnotsend-hthread != m_clientarray.getat(idx).hthread |pnotsend-m_strip != m_clientarray.getat(id

21、x).m_strip) send(m_clientarray.getat(idx).m_socket, (char *)szbuf, _tcslen(szbuf)*sizeof(tchar), 0);void cchatroomdlg:onenchangeinputmsg()cstring strmsg;getdlgitemtext(idc_input_msg, strmsg);if ( strmsg.isempty() ) enablewindow(idc_sendmsg, false);elseenablewindow(idc_sendmsg);void cchatroomdlg:stop

22、client()bshutdown = true;dword dwret = waitforsingleobject(m_hconnectthred, 1000);if ( dwret != wait_object_0 ) terminatethread(m_hconnectthred, -1);closesocket(m_connectsock);m_hconnectthred = null;m_connectsock = invalid_socket;m_bisserver = -1;bshutdown = false;void cchatroomdlg:stopserver()uint

23、ncount = m_clientarray.getcount();handle *m_phandles = new handlencount+1;m_phandles0 = m_hlistenthread;for( int idx = 0; idx ncount; idx+ ) m_phandlesidx+1 = m_clientarray.getat(idx).hthread;bshutdown = true;dword dwret = waitformultipleobjects(ncount+1, m_phandles, true, 1000);if ( dwret != wait_o

24、bject_0 ) for( int_ptr i = 0; i getwindowrect(&mrect);pt = mrect.bottomright();pt.y = mrect.top+10;mmenu.loadmenu(idr_menu1);pmenu = mmenu.getsubmenu(0);pmenu-trackpopupmenu(tpm_leftalign | tpm_rightbutton, pt.x, pt.y, this);bool cchatroomdlg:traymyicon(bool badd)bool bret = false;notifyicondata tnd

25、;tnd.cbsize = sizeof(notifyicondata);tnd.hwnd = getsafehwnd();tnd.uid = idr_mainframe;if ( badd = true ) tnd.uflags = nif_message | nif_icon | nif_tip;tnd.ucallbackmessage = wm_trayicon_msg;tnd.hicon = loadicon(afxgetinstancehandle(), makeintresource(idr_mainframe);_tcscpy_s(tnd.sztip, sizeof(tnd.sz

26、tip), _t(聊天室v1.0);showwindow(sw_minimize);showwindow(sw_hide);bret = shell_notifyicon(nim_add, &tnd);elseshowwindow(sw_showna);setforegroundwindow();bret = shell_notifyicon(nim_delete, &tnd);return bret;void cchatroomdlg:onmenutrayinco()traymyicon();lresult cchatroomdlg:ontraycallbackmsg(wparam wpar

27、am, lparam lparam)switch(lparam)case wm_rbuttonup:cmenu mmenu, *pmenu = null;cpoint pt;mmenu.loadmenu(idr_menu2);pmenu = mmenu.getsubmenu(0);getcursorpos(&pt);setforegroundwindow();pmenu-trackpopupmenu(tpm_leftalign | tpm_rightbutton, pt.x, pt.y, this);break;case wm_lbuttondblclk:showwindow(sw_resto

28、re);setforegroundwindow();traymyicon(false);break; 3. 附錄:課程設(shè)計(jì)中要用到的winsock函數(shù)wsastartup初始化socket庫(kù)wsacleanup結(jié)束socket庫(kù)的使用socket為所要進(jìn)行的網(wǎng)絡(luò)通信建立標(biāo)識(shí)符connect連接到遠(yuǎn)程主機(jī)closesocket結(jié)束通信,關(guān)閉標(biāo)識(shí)符bind將ip地址、tcp端口號(hào)與套接字標(biāo)識(shí)符綁定listen將接受套接字置于被動(dòng)模式,將服務(wù)器置于偵聽狀態(tài),并指定允許的連接數(shù)accept接受下一個(gè)呼入的連接recv接收傳入的tcp數(shù)據(jù)recvfrom接收傳入的udp數(shù)據(jù)select在指定的套接字集準(zhǔn)

29、備好接收數(shù)據(jù)前一直等待send發(fā)送tcp數(shù)據(jù)sendto發(fā)送udp數(shù)據(jù)shutdown釋放tcp連接getpeername從套接字中獲取對(duì)等方的端口地址setsocketopt獲取當(dāng)前套接字的可變選項(xiàng)gethostbynameinet_addr把域名轉(zhuǎn)換成網(wǎng)絡(luò)ip地址把用點(diǎn)分十進(jìn)制表示的ip地址轉(zhuǎn)換成網(wǎng)絡(luò)ip地址getservbynamegetprotobyname獲得服務(wù)器的端口號(hào)把tcp、udp轉(zhuǎn)換成相應(yīng)的服務(wù)號(hào)碼(interger)六、 調(diào)試過程測(cè)試的目的是為了發(fā)現(xiàn)功能是否達(dá)到,或者是否有更多的缺陷。當(dāng)兩個(gè)客戶端在建立連接時(shí),出現(xiàn)過程序假死異常。分析代碼發(fā)現(xiàn),線程調(diào)度出錯(cuò),接收消息線程t

30、h還未創(chuàng)建和啟動(dòng),監(jiān)聽線程wait已經(jīng)被銷毀了。修改代碼,給出兩種解決辦法:(1)在th線程的執(zhí)行方法中,將wait線程銷毀;在th線程銷毀前,重新開啟wait線程。(2)wait線程不銷毀。設(shè)置一bool類型變量isconnected,當(dāng)已經(jīng)建立連接后,isconnected=true,若再有其他的連接請(qǐng)求到達(dá),自動(dòng)將其他連接請(qǐng)求拒絕。連接斷開后,重置isconnected=false,將處理移交給用戶。我采用了第一種方法,調(diào)試之后,問題解決。在程序退出時(shí),常常發(fā)生錯(cuò)誤,異常退出,造成表面上看程序已結(jié)束,但卻仍然駐留在內(nèi)存中的現(xiàn)象。經(jīng)過反復(fù)分析代碼,最終確定問題出在程序退出處理流程上,通過修

31、改和調(diào)試,問題解決。軟件圖示七、 實(shí)驗(yàn)結(jié)果分析整個(gè)開發(fā)過程中,共歷經(jīng)多次相互斷開、連接測(cè)試,聊天模塊終于可以正常運(yùn)行。借助在文本聊天模塊開發(fā)過程中積累的經(jīng)驗(yàn),較順利的完成了文件傳輸模塊的開發(fā)。通過在總集成后的程序的各個(gè)流程中添加消息提示框顯示程序內(nèi)部數(shù)據(jù)、對(duì)象的狀態(tài),并插入斷點(diǎn)進(jìn)行單步跟蹤發(fā)現(xiàn)各模塊工作正常,數(shù)據(jù)也未發(fā)生異?,F(xiàn)象。(1)程序啟動(dòng)之后就能看到當(dāng)前哪些機(jī)器在線,哪些可以與之進(jìn)行對(duì)等通信。(2)一旦有某個(gè)網(wǎng)內(nèi)的機(jī)器上線了,要有即時(shí)通知,并能及時(shí)更新用戶界面中的用戶列表。(3)當(dāng)雙擊某個(gè)列表項(xiàng)的時(shí)候,要彈出聊天對(duì)話框,可以在其中編輯要發(fā)送的聊天信息,并進(jìn)行發(fā)送。(4)聊天界面要人性化,下面是發(fā)送框,上面有已有聊天記錄,并借助滾動(dòng)條看到當(dāng)次所有的聊天記錄。(5)當(dāng)有遠(yuǎn)程用戶向本機(jī)發(fā)送文件的時(shí)候,要彈出一個(gè)消息提示框,提示本機(jī)用戶,可以選擇接收或者拒絕。(6)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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)論