《綜合課程設(shè)計》設(shè)計報告基于Socket的即時通訊系統(tǒng)
《《綜合課程設(shè)計》設(shè)計報告基于Socket的即時通訊系統(tǒng)》由會員分享,可在線閱讀,更多相關(guān)《《綜合課程設(shè)計》設(shè)計報告基于Socket的即時通訊系統(tǒng)(19頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、 評閱教師評語: 課程設(shè)計成績 考勤成績 實做成績 報告成績 總評成績 指導(dǎo)教師簽名: 《綜合課程設(shè)計》 設(shè) 計 報 告 論文題目: 基于Socket的即時通訊系統(tǒng) 學(xué)院(系): 電子信息與自動化學(xué)院 班 級: 72——1 學(xué)生姓名: 學(xué)號 指導(dǎo)教師: 時間: 2011 年 6月 7日 到 20
2、11 年 6 月 17日 一、 設(shè)計目的 通過綜合課程設(shè)計,使學(xué)生能夠運用《數(shù)字信號處理》、《信號與系統(tǒng)》、《通信原理》、《面向?qū)ο蟮某绦蛟O(shè)計》、《計算機通信網(wǎng)》、《通信協(xié)議開發(fā)及應(yīng)用》等課程的知識來設(shè)計一個基于Socket的即時通訊系統(tǒng),培養(yǎng)學(xué)生的動手能力以及分析問題、解決問題的能力。 二、 設(shè)計內(nèi)容 一個基于Socket的即時通訊系統(tǒng)的多人聊天軟件 三、 設(shè)計要求 (一)基本要求 1. 熟練掌握面向?qū)ο蟮某绦蛟O(shè)計方法; 2. 實現(xiàn)點對點通訊,能進行文字對話傳輸,包括客戶端與服務(wù)器端; 3. 能對系統(tǒng)參數(shù)進行配置。 (二)提高要求 1、實現(xiàn)文件、
3、圖片傳輸; 2、語音對話(兩人及兩人以上); 3、友好的對話界面。 四、 設(shè)計原理 1 TCP/IP簡介 TCP/IP的歷史要追溯到70年代中期,當(dāng)時ARPA為了實現(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ù)統(tǒng)計,到1990年,Internet以包含遍布歐美的五千個活動網(wǎng)絡(luò),超過三十萬臺機算機.作為一種事實上的工標(biāo)準(zhǔn),
4、TCP/IP技術(shù)方興未艾. 2 TCP/IP的網(wǎng)絡(luò)分層結(jié)構(gòu) 對TCP/IP協(xié)議來說,TCP提供傳輸層服務(wù),IP提供網(wǎng)絡(luò)層服務(wù).TCP/IP協(xié)議組(或Internet協(xié)議組)的分層結(jié)構(gòu)及其與OSI模型的對應(yīng)關(guān)系如圖4所示.圖中有關(guān)協(xié)議的名稱及其基本含義如下: (1) TCP. 為傳輸控制協(xié)議(Transmission Control Protocol).它是提供給用戶進程的一個可靠的全雙工字節(jié)流的面向連接的協(xié)議.大多數(shù)Internet應(yīng)用程序使用TCP.因為TCP使用IP,所以整個Internet協(xié)議組也常稱為TCP/IP協(xié)議組. (2) UDP. 為用戶數(shù)據(jù)報協(xié)議 (
5、User Datagram Protocol). (3) ICMP. 為網(wǎng)間報文控制協(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)間網(wǎng)進程通信問題.Socket接口為進程間通信提供了一種新的手段,它
6、不但能用于同一機器中的進程之間的通信,而且支持網(wǎng)絡(luò)通信功能.Socket具有類型,反應(yīng)了對用戶透明的通信特性. 一個完整的Socket連接用一個相關(guān)描述: { 協(xié)議,本地地址,本地端口,遠地地址,遠地端口 } Socket 是面向客戶-服務(wù)器模型而設(shè)計的,針對客戶和服務(wù)器程序提供不同的Socket系統(tǒng)調(diào)用. (2) Socket系統(tǒng)調(diào)用 不管Socket內(nèi)部機制如何,它提供給應(yīng)用程序員的最終界面是一組系統(tǒng)功能調(diào)用.下面,我們一一給出重要的Socket系統(tǒng)調(diào)用. 1. 創(chuàng)建 Socket ----- socket() 調(diào)用格式如下:
7、 sockid = socket (af,type,protocol) af : 地址族,指本socket所用地址類型. type : 類型,指創(chuàng)建socket的應(yīng)用程序所希望的通信服務(wù)器類型. protocol : 協(xié)議,指本socket請求的協(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,add
8、rlen) sockid : socket號. localaddr : 本地socket地址. addrlen : 地址長度. 3. 建立socket連接 ---- connect () 與 accept ()調(diào)用 這兩個系統(tǒng)調(diào)用用于完成整個相關(guān)的建立.其中connect用于建立連接 .調(diào)用格為: connect (sockid,destaddr,addrlen) destaddr : 指向?qū)Ψ絪ocket地址(信宿地址)結(jié)構(gòu)的指針. accept : 用于面向連接的服務(wù)器,其調(diào)用格式為: news
9、ock = accept (sockid,clientaddr,paddrlen) clientaddr : 指向客戶socket地址指針. paddrlen : 客戶socket地址長度. 4. listen() 調(diào)用 此調(diào)用用于面向連接服務(wù)器,表明它愿意接收連接,listen()在accept()之前調(diào)用,格式為: listen (sockid,quelen) quelen : 請求隊列長度. 5. 發(fā)送數(shù)據(jù) ---- write(),writev(),send()與sendto(),sendms
10、g() 用于socket數(shù)據(jù)發(fā)送的系統(tǒng)調(diào)用一共有五個,其中三個,write(),writev()和send()用于面向連接傳輸,其余兩個用于無連接傳輸.面向連接的調(diào)用可以不指定信宿地址,而無連接的調(diào)用必須指定.假如無連接socket的雙方均調(diào)用過connect(),可以認為是建立有連接的socket,也可以面向連接調(diào)用發(fā)送數(shù)據(jù). 三個面向連接調(diào)用三者的格式大致相同: write (sockid,buff,bufflen) : 緩沖發(fā)送 writev (sockid,iovector,vectorlen) : 集中發(fā)送 send (sockid,buff,
11、bufflen,flags) : 可控緩沖發(fā)送 其中buff指向發(fā)送緩沖區(qū)的指針,bufflen是發(fā)送緩沖區(qū)大小. 用于無連接數(shù)據(jù)發(fā)送的調(diào)用有兩個: sendto (sockid,buff,bufflen,flags,dsadd,addrlen) sendmsg (sockid,message,flags):可控集中無連接發(fā)送. 6. 接收數(shù)據(jù) ---- read(),readv(),recv()與recvfrom(),recvmsg() 接收數(shù)據(jù)與發(fā)送數(shù)據(jù)系統(tǒng)調(diào)用是一一對應(yīng)的,兩者參數(shù)的最大區(qū)別是,前者buffer是一個指針,其所指單元
12、初值為欲讀數(shù)據(jù)長度,調(diào)用后的值是實際讀出的值. 4 客戶--服務(wù)器模型的Socket實現(xiàn)框架 1)客戶--服務(wù)器模型時序圖 下圖是面向連接客戶--服務(wù)器模型的典型時序圖 服務(wù)器 客戶 socket() socket() bind() bind() listen() accept() 等待客戶連接請求 阻塞 <━━━━━━━━━━━━━━━ connect()
13、 read() <━━━━━━━━━━━━━━━> write() 2)服務(wù)器socket地址的確定 在客戶--服務(wù)器模型中,所有的作用者都是客戶首先發(fā)起的(如連接請求,服務(wù)請求等),因此客戶必須要知道服務(wù)器socket地址,另外,客戶調(diào)用服務(wù)器之前,可以在命令行中給出服務(wù)器所在主機的域名,根據(jù)域名可以獲得服務(wù)器主機的地址,系統(tǒng)調(diào)用為:hp=gethostbyname(host).其中host可以是服務(wù)器主機域名,返回hp是一個指向主機地址結(jié)構(gòu)的指針。 五、 軟件設(shè)計(附程序流程圖、源程序清單) 1. 程序流程圖 2.源程序清單 void CChatR
14、oomDlg::DlgAllInit() { CheckRadioButton(IDC_RADIO_CLIENT, IDC_RADIO_SERVER, IDC_RADIO_CLIENT); SetDlgItemText(IDC_IP_ADDR, _T("127.0.0.1")); // 初始化ip地址為本機地址。 SetDlgItemText(IDC_CONNECT_PORT, _T("5566")); // 初始化端口。 SetDlgItemText(IDC_LISTEN_PORT, _T("5566")); EnableWindow(IDC_STOP_CLI
15、ENT, FALSE); EnableWindow(IDC_LISTEN_PORT, FALSE); EnableWindow(IDC_STOP_SERVER, FALSE); EnableWindow(IDC_START_SERVER, FALSE); EnableWindow(IDC_STATIC_LISTEN_PORT, FALSE); // 初始化按鍵啟用or禁用。 EnableWindow(IDC_SENDMSG, FALSE); } BOOL CChatRoomDlg::EnableWindow(UINT uID, BOOL bEnable)
16、 { return GetDlgItem(uID)->EnableWindow(bEnable); } void CChatRoomDlg::ExtendDiaog(BOOL bShow) { static CRect m_DlgRectLarge(0, 0, 0, 0); static CRect m_DlgRectSmall(0, 0, 0, 0); static CRect m_GroupRectLarge(0, 0, 0, 0); static CRect m_GroupRectSmall(0, 0, 0, 0); // 設(shè)置 窗口大小
17、 if ( m_DlgRectLarge.IsRectNull() ) { GetWindowRect(&m_DlgRectLarge); m_DlgRectSmall = m_DlgRectLarge; m_DlgRectSmall.right -= 220; ::GetWindowRect(GetDlgItem(IDC_FRAME)->GetSafeHwnd(), &m_GroupRectLarge); m_GroupRectSmall = m_GroupRectLarge; m_GroupRectSmall.right -= 220;
18、 // 設(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_GroupRectLarge.Width(), m_GroupRectLarge.Height(), SWP_
19、NOZORDER | SWP_NOMOVE); }else{ bShowAll = 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.Height(), SWP_NOZORDER | SWP_N
20、OMOVE); } } void CChatRoomDlg::OnBnClickedNetset() { if ( bShowAll ) { ExtendDiaog(FALSE); }else{ ExtendDiaog(TRUE); // 設(shè)置按鍵“網(wǎng)絡(luò)設(shè)置”的作用 } } void CChatRoomDlg::OnBnClickedStartServer() { m_hListenThread = CreateThread(NULL, 0, ListenThreadFunc, this, 0,
21、NULL);
}
void CChatRoomDlg::ShowMsg(CString strMsg)
{
m_MsgEdit.SetSel(-1, -1);
m_MsgEdit.ReplaceSel(strMsg+_T("\r\n"));
}
void CChatRoomDlg::RemoveClientFromArray(CClientItem in_Item)
{
for( int idx = 0; idx 22、etAt(idx);
if ( tItem.m_Socket == in_Item.m_Socket &&
tItem.hThread == in_Item.hThread &&
tItem.m_strIp == in_Item.m_strIp ) {
m_ClientArray.RemoveAt(idx);
}
}
}
void CChatRoomDlg::OnBnClickedSendmsg()
{
CString strMsg;
GetDlgItemText(IDC_INPUT_MSG, strMs 23、g);
if ( m_bIsServer == TRUE ) {
strMsg = _T("張智超的服務(wù)器:>") + strMsg;
ShowMsg(strMsg);
SendClientsMsg(strMsg);
}else if (m_bIsServer == FALSE) {
CString strTmp = _T("張智超的客戶端:>") + strMsg;
ShowMsg(strTmp);
int iSend = send(m_ConnectSock, (char *)strMsg.GetBuffer(), strMsg.GetLengt 24、h()*sizeof(TCHAR), 0);
strMsg.ReleaseBuffer();
}else{
AfxMessageBox(_T("請您先進入聊天室!"));
}
SetDlgItemText(IDC_INPUT_MSG, _T(""));
} // socket 基本應(yīng)用
void CChatRoomDlg::OnBnClickedStartClient()
{
m_hConnectThred = Cre 25、ateThread(NULL, 0, ConnectThreadFunc, this, 0, NULL);
}
void CChatRoomDlg::SendClientsMsg(CString strMsg, CClientItem *pNotSend)
{
TCHAR szBuf[MAX_BUF_SIZE] = {0};
_tcscpy_s(szBuf, MAX_BUF_SIZE, strMsg);
for( INT_PTR idx = 0; idx < m_ClientArray.GetCount(); idx++ ) {
if ( !pNotSend || 26、pNotSend->m_Socket != m_ClientArray.GetAt(idx).m_Socket || pNotSend->hThread != m_ClientArray.GetAt(idx).hThread ||
pNotSend->m_strIp != m_ClientArray.GetAt(idx).m_strIp) {
send(m_ClientArray.GetAt(idx).m_Socket, (char *)szBuf, _tcslen(szBuf)*sizeof(TCHAR), 0);
}
}
}
void CChatRoomDl 27、g::OnEnChangeInputMsg()
{
CString strMsg;
GetDlgItemText(IDC_INPUT_MSG, strMsg);
if ( strMsg.IsEmpty() ) {
EnableWindow(IDC_SENDMSG, FALSE);
}else{
EnableWindow(IDC_SENDMSG);
}
}
void CChatRoomDlg::StopClient()
{
bShutDown = TRUE;
DWORD dwRet = WaitForSingleObject(m_hConnec 28、tThred, 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 nCount = m_ClientArray.Get 29、Count();
HANDLE *m_pHandles = new HANDLE[nCount+1];
m_pHandles[0] = m_hListenThread;
for( int idx = 0; idx < nCount; idx++ ) {
m_pHandles[idx+1] = m_ClientArray.GetAt(idx).hThread;
}
bShutDown = TRUE;
DWORD dwRet = WaitForMultipleObjects(nCount+1, m_pHandles, TRUE, 1000);
if ( dwRet 30、 != WAIT_OBJECT_0 ) {
for( INT_PTR i = 0; i < m_ClientArray.GetCount(); i++ ) {
TerminateThread(m_ClientArray.GetAt(i).hThread, -1);
closesocket(m_ClientArray.GetAt(i).m_Socket);
}
TerminateThread(m_hListenThread, -1);
closesocket(m_ListenSock);
}
delete [] m_pHandles;
m_hL 31、istenThread = NULL;
m_ListenSock = INVALID_SOCKET;
m_bIsServer = -1;
bShutDown = FALSE;
}
void CChatRoomDlg::OnBnClickedStopClient()
{
StopClient();
ShowMsg(_T("停止客戶端成功!"));
EnableWindow(IDC_START_CLIENT);
EnableWindow(IDC_STOP_CLIENT, FALSE);
}
void CChatRoomDlg::OnBnClickedS 32、topServer()
{
StopServer();
ShowMsg(_T("停止服務(wù)器成功!"));
EnableWindow(IDC_START_SERVER);
EnableWindow(IDC_STOP_SERVER, FALSE);
}
void CChatRoomDlg::OnBnClickedRadioClient()
{
int iRet = -1;
if ( m_bIsServer == TRUE ) {
int iRet = MessageBox(_T("您是聊天室的服務(wù)器端,如果您退出,所有的客戶端都將掉線!\r\n您確定退出嗎 33、?"), _T("提示"), MB_OKCANCEL | MB_ICONWARNING);
if ( iRet == IDOK ) {
StopServer();
}else{
CheckRadioButton(IDC_RADIO_CLIENT, IDC_RADIO_SERVER, IDC_RADIO_SERVER);
}
}
if ( iRet == IDOK || m_bIsServer == -1 ) {
EnableWindow(IDC_IP_ADDR);
EnableWindow(IDC_CONNECT_PORT);
Ena 34、bleWindow(IDC_STATIC_SERVER_IP);
EnableWindow(IDC_STATIC_SERVER_PORT);
EnableWindow(IDC_START_CLIENT);
EnableWindow(IDC_STOP_CLIENT, FALSE);
EnableWindow(IDC_LISTEN_PORT, FALSE);
EnableWindow(IDC_STOP_SERVER, FALSE);
EnableWindow(IDC_START_SERVER, FALSE);
EnableWindow(IDC_STAT 35、IC_LISTEN_PORT, FALSE);
}
}
void CChatRoomDlg::OnBnClickedRadioServer()
{
int iRet = -1;
if ( m_bIsServer == FALSE ) {
int iRet = MessageBox(_T("您正在聊天室中,確定退出嗎?"), _T("提示"), MB_OKCANCEL | MB_ICONWARNING);
if ( iRet == IDOK ) {
StopClient();
}else{
CheckRadioButton(IDC_RADI 36、O_CLIENT, IDC_RADIO_SERVER, IDC_RADIO_CLIENT);
}
}
if ( iRet == IDOK || m_bIsServer == -1) {
EnableWindow(IDC_LISTEN_PORT);
EnableWindow(IDC_STOP_SERVER, FALSE);
EnableWindow(IDC_START_SERVER);
EnableWindow(IDC_STATIC_LISTEN_PORT);
EnableWindow(IDC_IP_ADDR, FALSE);
EnableW 37、indow(IDC_CONNECT_PORT, FALSE);
EnableWindow(IDC_STATIC_SERVER_IP, FALSE);
EnableWindow(IDC_STATIC_SERVER_PORT, FALSE);
EnableWindow(IDC_START_CLIENT, FALSE);
EnableWindow(IDC_STOP_CLIENT, FALSE);
}
}
void CChatRoomDlg::OnBnClickedCancel()
{
if ( m_bIsServer == TRUE ) {
StopS 38、erver();
}else if ( m_bIsServer == FALSE ) {
StopClient();
}
OnCancel();
}
void CChatRoomDlg::OnBnClickedOther()
{
CPoint pt;
CRect mRect;
CMenu mMenu, *pMenu = NULL;
GetDlgItem(IDC_OTHER)->GetWindowRect(&mRect);
pt = mRect.BottomRight();
pt.y = mRect.top+10;
mMenu.LoadMe 39、nu(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;
tnd.cbSize = sizeof(NOTIFYICONDATA);
tnd.hWnd = GetSafeHwnd();
tnd.uID = IDR_MA 40、INFRAME;
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.szTip), _T("聊天室v1.0"));
ShowWindow(SW_MINIMIZE);
Sho 41、wWindow(SW_HIDE);
bRet = Shell_NotifyIcon(NIM_ADD, &tnd);
}else{
ShowWindow(SW_SHOWNA);
SetForegroundWindow();
bRet = Shell_NotifyIcon(NIM_DELETE, &tnd);
}
return bRet;
}
void CChatRoomDlg::OnMenuTrayinco()
{
TrayMyIcon();
}
LRESULT CChatRoomDlg::OnTrayCallBackMsg(WPARAM 42、 wparam, 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, 43、pt.y, this);
break;
}
case WM_LBUTTONDBLCLK:
ShowWindow(SW_RESTORE);
SetForegroundWindow();
TrayMyIcon(FALSE);
break;
3. 附錄:課程設(shè)計中要用到的Winsock函數(shù)
WSAStartup
初始化socket庫
WSACleanup
結(jié)束socket庫的使用
socket
為所要進行的網(wǎng)絡(luò)通信建立標(biāo)識符
connect
連接到遠程主機
closesocket
結(jié)束通信,關(guān)閉標(biāo)識符
bind
將IP地址、TCP 44、端口號與套接字標(biāo)識符綁定
listen
將接受套接字置于被動模式,
將服務(wù)器置于偵聽狀態(tài),并指定允許的連接數(shù)
accept
接受下一個呼入的連接
recv
接收傳入的TCP數(shù)據(jù)
recvfrom
接收傳入的UDP數(shù)據(jù)
select
在指定的套接字集準(zhǔn)備好接收數(shù)據(jù)前一直等待
send
發(fā)送TCP數(shù)據(jù)
sendto
發(fā)送UDP數(shù)據(jù)
shutdown
釋放TCP連接
getpeername
從套接字中獲取對等方的端口地址
setsocketopt
獲取當(dāng)前套接字的可變選項
gethostbyname
inet_addr
把域名轉(zhuǎn)換成網(wǎng)絡(luò)IP地址
45、把用點分十進制表示的IP地址轉(zhuǎn)換成網(wǎng)絡(luò)IP地址
getservbyname
getprotobyname
獲得服務(wù)器的端口號
把TCP、UDP轉(zhuǎn)換成相應(yīng)的服務(wù)號碼(interger)
六、 調(diào)試過程
測試的目的是為了發(fā)現(xiàn)功能是否達到,或者是否有更多的缺陷。
當(dāng)兩個客戶端在建立連接時,出現(xiàn)過程序假死異常。分析代碼發(fā)現(xiàn),線程調(diào)度出錯,接收消息線程th還未創(chuàng)建和啟動,監(jiān)聽線程wait已經(jīng)被銷毀了。修改代碼,給出兩種解決辦法:(1)在th線程的執(zhí)行方法中,將wait線程銷毀;在th線程銷毀前,重新開啟wait線程。(2)wait線程不銷毀。設(shè)置一bool類型變量isconnect 46、ed,當(dāng)已經(jīng)建立連接后,isconnected=true,若再有其他的連接請求到達,自動將其他連接請求拒絕。連接斷開后,重置isconnected=false,將處理移交給用戶。我采用了第一種方法,調(diào)試之后,問題解決。
在程序退出時,常常發(fā)生錯誤,異常退出,造成表面上看程序已結(jié)束,但卻仍然駐留在內(nèi)存中的現(xiàn)象。經(jīng)過反復(fù)分析代碼,最終確定問題出在程序退出處理流程上,通過修改和調(diào)試,問題解決。
軟件圖示
七、 實驗結(jié)果分析
整個開發(fā)過程中,共歷經(jīng)多次相互斷開、連接測試,聊天模塊終于可以正常運行。借助在文本聊天模塊開發(fā)過程中積累的 47、經(jīng)驗,較順利的完成了文件傳輸模塊的開發(fā)。通過在總集成后的程序的各個流程中添加消息提示框顯示程序內(nèi)部數(shù)據(jù)、對象的狀態(tài),并插入斷點進行單步跟蹤發(fā)現(xiàn)各模塊工作正常,數(shù)據(jù)也未發(fā)生異?,F(xiàn)象。
(1)程序啟動之后就能看到當(dāng)前哪些機器在線,哪些可以與之進行對等通信。
(2)一旦有某個網(wǎng)內(nèi)的機器上線了,要有即時通知,并能及時更新用戶界面中的用戶列表。
(3)當(dāng)雙擊某個列表項的時候,要彈出聊天對話框,可以在其中編輯要發(fā)送的聊天信息,并進行發(fā)送。
(4)聊天界面要人性化,下面是發(fā)送框,上面有已有聊天記錄,并借助滾動條看到當(dāng)次所有的聊天記錄。
(5)當(dāng)有遠程用戶向本機發(fā)送文件的時候,要彈出一個消息提示框, 48、提示本機用戶,可以選擇接收或者拒絕。
(6)當(dāng)用戶覺得有必要保存聊天記錄時,提供一個簡單的聊天記錄保存功能。
(7)文件傳輸過程中,應(yīng)該有當(dāng)前傳輸狀態(tài)提示,并能夠?qū)鬏敽臅r等進行計算,作為當(dāng)前網(wǎng)絡(luò)狀態(tài)的一種反饋。
經(jīng)檢查,當(dāng)用戶輸入無效操作時,系統(tǒng)總是能檢測到無效操作,對用戶進行相應(yīng)的信息反饋,并合理的做出內(nèi)部處理。當(dāng)系統(tǒng)本身發(fā)生錯誤,比如網(wǎng)絡(luò)初始化失敗,綁定套接字失敗,數(shù)據(jù)讀取失敗等,都會進行相對應(yīng)的正確處理。
八、 體會和建議
通過這些時間的開發(fā)設(shè)計,開發(fā)基于Socket的聊天系統(tǒng)已經(jīng)可以按照預(yù)定要求實現(xiàn)功能,完全實現(xiàn)了聊天、文件傳輸?shù)裙δ?。隨著科技的發(fā)展和社會的進步,聊天系統(tǒng)將 49、需要得到進一步改善,相應(yīng)的功能模塊也應(yīng)相應(yīng)的增加,比如多媒體方面的內(nèi)容,以滿足用戶需求。
通過此次的論文,我學(xué)到了很多知識,跨越了傳統(tǒng)方式下的教與學(xué)的體制束縛,在論文的寫作過程中,通過查資料和搜集有關(guān)的文獻,培養(yǎng)了自學(xué)能力和動手能力。并且由原先的被動的接受知識轉(zhuǎn)換為主動的尋求知識,這可以說是學(xué)習(xí)方法上的一個很大的突破。在以往的傳統(tǒng)的學(xué)習(xí)模式下,我們可能會記住很多的書本知識,但是通過畢業(yè)論文,我們學(xué)會了如何將學(xué)到的知識轉(zhuǎn)化為自己的東西,學(xué)會了怎么更好的處理知識和實踐相結(jié)合的問題。在論文的寫作過程中也學(xué)到了做任何事情所要有的態(tài)度和心態(tài),首先做學(xué)問要一絲不茍,對于發(fā)展過程中出現(xiàn)的任何問題和偏差都不 50、要輕視,要通過正確的途徑去解決,在做事情的過程中要有耐心和毅力,不要一遇到困難就達退堂鼓,只要堅持下去就可以找到思路去解決問題的。而且要學(xué)會與人合作,這樣做起事情來就可以事倍功半。
總之,此次課設(shè)的寫作過程,我收獲了很多,即為將來的人生之路做好了一個很好的鋪墊。
九、 參考文獻
[1] Karli Watson,Christian Nagel等.C#入門經(jīng)典(第3版)[M].北京:清華大學(xué)出版社.2004.
[2] 宋振會.SQL Server 2000中文版基礎(chǔ)教程[M].北京:清華大學(xué)出版社.2005.
[3] Karli Watson等.Beginning Visual C# 2005[M].北京:清華大學(xué)出版.社.2005.
[4] Jim Arlow Ila Neustadt.UML和統(tǒng)一過程[M].北京:機械工業(yè)出版社.2003.2.
[5] 佩里.C#和.NET核心技術(shù)[M].北京:機械工業(yè)出版社.2006.7.
[6] 天極網(wǎng)新技術(shù)研究室.ASP.NET完全入門[M].北京:重慶出版社.2001.
[7] Scott Worley.ASP.NET技術(shù)內(nèi)幕[M].北京:人民郵電出版社.2002.
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 火力發(fā)電廠各設(shè)備的主要作用大全
- 3.高壓電工考試判斷練習(xí)題含答案
- 企業(yè)電氣防爆知識
- 13 低壓電工電工作業(yè)模擬考試題庫試卷含答案
- 電氣設(shè)備維修的十項原則
- 2.電氣電纜與直流模擬考試復(fù)習(xí)題含答案
- 電氣節(jié)能措施總結(jié)
- 2.電氣電機(一)模擬考試復(fù)習(xí)題含答案
- 接地電阻測量原理與測量方法
- 3.高壓電工作業(yè)模擬考試題庫試卷含答案
- 礦山維修電工安全技術(shù)操作規(guī)程
- 電工基礎(chǔ)口訣總結(jié)
- 3.某電廠值長面試題含答案解析
- 電工基礎(chǔ)知識順口溜
- 配電系統(tǒng)詳解