宋毅
摘要:隨著網(wǎng)絡(luò)編程應(yīng)用軟件普及,用戶使用網(wǎng)絡(luò)應(yīng)用更加廣泛,對于技術(shù)人員掌握多線程技術(shù)在網(wǎng)絡(luò)程序設(shè)計(jì)中的應(yīng)用,理解流式套接字程序設(shè)計(jì)模型,熟悉WinSock套接字庫的加載,熟練掌握各類WinSock中API函數(shù)。該聊天室分為客戶端和服務(wù)器端兩端設(shè)計(jì)與實(shí)現(xiàn)。設(shè)計(jì)網(wǎng)絡(luò)聊天室對于用戶具有實(shí)際應(yīng)用價(jià)值。
關(guān)鍵詞:VS;網(wǎng)絡(luò)編程;聊天室
中圖分類號(hào):TP311 ? ? ? ?文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1009-3044(2020)17-0085-02
Abstract:With the popularization of network programming application software, users use network applications more widely. For technicians to master the application of multithreading technology in network programming, understand the flow socket programming model, be familiar with the loading of Winsock socket socket library, and master API functions in various Winsock. The chat room is divided into client and server-side design and implementation. The design of network chat room has practical application value for users.
Key words:VS;network programming;chat room
1 基礎(chǔ)知識(shí)
WinSock的加載,建立監(jiān)聽、接受連接、數(shù)據(jù)發(fā)送和數(shù)據(jù)接受使用的WinSock中的listen、connect、send和recv;發(fā)送數(shù)據(jù)是.NET中寬字節(jié)和多字節(jié)的相互轉(zhuǎn)換;線程函數(shù)的定義和線程啟動(dòng)。
2 設(shè)計(jì)步驟
2.1 服務(wù)端程序設(shè)計(jì)
1)創(chuàng)建項(xiàng)目
創(chuàng)建一個(gè)對話框應(yīng)用程序,項(xiàng)目名稱為“Fuwuqi”,在創(chuàng)建向?qū)е性O(shè)置“Windows套接字”,支持網(wǎng)絡(luò)編程,其他采用默認(rèn)設(shè)置,設(shè)計(jì)對話框如圖1所示。添加一個(gè)列表控件,為其關(guān)聯(lián)CListCtrl類型的變量m_list,設(shè)置控件的View屬性為report,添加編輯框,為其關(guān)聯(lián)CString類型的變量bianjikuang,添加按鈕,為其建立消息映射。注意,添加成員變量過程如果有誤,請刪除對應(yīng)頭文件和源文件內(nèi)的成員變量名字,重新填寫即可。
2)修改FuwuqiDlg.h文件,頭文件需要添加例如變量的聲明等
在FuwuqiDlg.h文件中添加線程函數(shù)聲明,代碼如下,注意不要在類內(nèi)寫。
UINT thread(LPVOID)
3)編輯服務(wù)器端函數(shù)內(nèi)容,寫入對應(yīng)程序
對話框程序自己帶初始化功能,初始化計(jì)數(shù)器相關(guān)參數(shù),首先調(diào)試這個(gè)函數(shù)的核心代碼如下:
libiaokuang.InsertColumn(0,_T("消息"));//列表框內(nèi)容顯示信息
libiaokuang.SetColumnWidth(0,435); //設(shè)置列表框?qū)挾?/p>
bianjikuang.fuwu.sin_family=AF_INET;
fuwu.sin_port=5000;/;
addlen=sizeof(fuwu);
sock=socket(AF_INET,SOCK_STREAM,0); //創(chuàng)建socket
if (bind(sock,(sockaddr*)&fuwu,addlen)) ?//綁定
bianjikuang = _T("綁定錯(cuò)誤");
else
{
m_edit = _T("服務(wù)器創(chuàng)建成功");
listen(sock,5); ? ? ? //開始偵聽
AfxBeginThread(&thread,0); ? ?//調(diào)用線程
}
//更新數(shù)據(jù)包
// 除非將焦點(diǎn)設(shè)置到控件,否則返回TRUE
}
void CFuwuerDlg::OnBnClickedSend()//發(fā)送消息核心代碼
{
libiaokuang.InsertItem(jishuqi++,bianjikuang);//插入計(jì)數(shù)統(tǒng)計(jì)
msgjishuqi=dlg->getjishuqi();//獲得客戶端flag { ?s=1; ?dlg->taojiezi[msgjishuqi]=accept(dlg->sock,(sockaddr*)&(dlg->fuwu),&(dlg->addlen));
if (dlg->taojiezi[msgjishuqi]==INVALID_SOCKET) /判斷連接是否有效套接字
dlg->bianjikuang = _T("連接錯(cuò)誤");
else
{ AfxBeginThread(thread,0); ? ? ?//啟動(dòng)線程
dlg->libiaokuang.InsertItem(dlg->jishuqi++,_T("連接成功"));
dlg->libiaokuang.Scroll(chicun);
while(s!=SOCKET_ERROR) ? ? //循環(huán)接收數(shù)據(jù)
{ s=recv(dlg->taojiezi[msgjishuqi],buff,100,0);
CString temp; //定義臨時(shí)變量
DWORD dwNum = ::MultiByteToWideChar (
CP_ACP, 0, buff, -1, NULL, 0);
wchar_t *pwText = new wchar_t[dwNum];
MultiByteToWideChar (CP_ACP, 0, buff, -1, pwText, dwNum);
temp.Format(_T("%s"),pwText);
delete []pwText;
//異常處理
dlg->libiaokuang.InsertItem(dlg->jishuqi++,_T("斷開連接"));
dlg->libiaokuang.Scroll(chicun);
dlg->taojiezi[msgjishuqi]=NULL;
for (int m=0;m<100;m++)
if (dlg->taojiezi[m]!=NULL) flag=1;
closesocket(dlg->taojiezi[msgjishuqi]);}} //終止線程
}
//getjishuqi()實(shí)現(xiàn)獲得還沒有使用的socket數(shù)組號(hào)
//sendtoall(SOCKET s,char *buff) 實(shí)現(xiàn)向所有客戶發(fā)送數(shù)據(jù)
2.2 客戶端程序設(shè)計(jì)
1)創(chuàng)建項(xiàng)目
創(chuàng)建一個(gè)對話框應(yīng)用程序,項(xiàng)目名稱為“Kehuaduan”,在創(chuàng)建向?qū)е性O(shè)置“Windows套接字”,支持網(wǎng)絡(luò)編程,其他采用默認(rèn)設(shè)置。添加一個(gè)列表控件,為其關(guān)聯(lián)CListCtrl類型的變量libiaokuang,設(shè)置控件的View屬性為report,添加兩個(gè)編輯框,分別為其關(guān)聯(lián)CString類型的變量m_ip和m_message,添加兩個(gè)按鈕,為其建立消息映射。
2)修改KehuaduanDlg.h文件,添加代碼如下:
在KehuaduanDlg.h文件中添加線程函數(shù)聲明,代碼如下,注意不要在類內(nèi)寫。
UINT thread(LPVOID);
3)修改KehuaduanDlg.cpp,各函數(shù)的代碼如下:
連接服務(wù)器核心
clisock=socket(AF_INET,SOCK_STREAM,0); //創(chuàng)建socket
AfxBeginThread(thread,0); ? ? //啟動(dòng)線程
//發(fā)送消息和服務(wù)器端類似
UINT thread(LPVOID v) //客戶端接收線程核心
{ connect(dlg->clisock,(sockaddr*)&(dlg->cli),chicunof(dlg->cli)); //連接到服務(wù)器
dlg->libiaokuang.InsertItem(dlg->jishuqi++,_T("連接成功"));
while(s!=SOCKET_ERROR) ? ? ? ?//循環(huán)獲得數(shù)據(jù)
{ s=recv(dlg->clisock,buff,100,0); ? ?//調(diào)用recv函數(shù)接收數(shù)據(jù)
CString temp;
DWORD dwNum = ::MultiByteToWideChar (CP_ACP, 0, buff, -1, NULL, 0);
wchar_t *pwText = new wchar_t[dwNum];
MultiByteToWideChar (CP_ACP, 0, buff, -1, pwText, dwNum);
temp.Format(_T("%s"),pwText);
delete []pwText;
dlg->libiaokuang.InsertItem(dlg->jishuqi++,temp);
dlg->libiaokuang.Scroll(chicun); }
send(dlg->clisock,"斷開連接",100,0); ? ? //發(fā)送斷開命令
closesocket(dlg->clisock);
}
編譯、鏈接并運(yùn)行兩個(gè)對話框程序,首先建立服務(wù)器監(jiān)聽,然后客戶端連接服務(wù)器,即可運(yùn)行測試。
參考文獻(xiàn):
[1] 任海峰,趙君.移動(dòng)學(xué)習(xí)國內(nèi)外研究現(xiàn)狀分析[J].成人教育,2010,30(1):95-96.
[2] 聶維,劉小豫.基于Linux的聊天室的設(shè)計(jì)與實(shí)現(xiàn)[J].電腦與電信,2018(9):27-28.
[3] 任琴,孔令慧,秦冰.基于JAVA的多人聊天室的系統(tǒng)設(shè)計(jì)[J].時(shí)代農(nóng)機(jī),2018,45(1):142.
[4] 董敏,桑建建.基于Linux的網(wǎng)絡(luò)聊天系統(tǒng)的設(shè)計(jì)[J].信息與電腦(理論版),2017(23):142-143.
[5] 張萍萍,紀(jì)志堅(jiān).基于Python的聊天軟件的設(shè)計(jì)與實(shí)現(xiàn)[J].網(wǎng)絡(luò)安全技術(shù)與應(yīng)用,2017(5):67-71.
[6] 常穎.基于ASP網(wǎng)絡(luò)聊天室設(shè)計(jì)與實(shí)現(xiàn)[J].電子技術(shù)與軟件工程,2017(05):70-71.
[7] 畢娜.局域網(wǎng)聊天室系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[J].福建電腦,2016,32(5):135-136,145.
[8] 胡楠.網(wǎng)頁即時(shí)聊天系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[J].信息與電腦(理論版),2015(7):19,21.
[9] 張龍.聊天系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[D].大連:大連理工大學(xué),2015.
[10] Wenjun Yang,Jiaying Zhang,Chundong Wang,et al. Situation prediction of large-scale Internet of Things network security[J].EURASIP Journal on Information Security,2019,2019(1).
【通聯(lián)編輯:代影】