日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

对做的一个小的C++聊天室的总结

發(fā)布時(shí)間:2023/12/10 c/c++ 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对做的一个小的C++聊天室的总结 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

這兩天照著教學(xué)視頻用C++做了個(gè)小的聊天室程序,只是實(shí)現(xiàn)接收端和發(fā)送端進(jìn)行簡(jiǎn)單的數(shù)據(jù)傳遞。主要分一下幾個(gè)步驟:

1、打開(kāi)vc++建立一個(gè)MFC AppWizard(exe)的工程我的工程名為Caht緊接著選擇一個(gè)“基本對(duì)話(huà)框”將其里面的三個(gè)空間都刪去。添加一個(gè)組框并改其標(biāo)題為”接受數(shù)據(jù)“,在組框中添加一個(gè)差不多大小的編輯框,改其ID為IDC_EDIT_RECV。接著在剛才那個(gè)組框下面在添加一個(gè)組框并將其標(biāo)題改為”發(fā)送數(shù)據(jù)“再這個(gè)組框中添加一個(gè)IP地址空間和一個(gè)編輯框并將編輯框的ID改為”IDC_EDIT_SEND“。再在這個(gè)組框的下面添加一個(gè)按鈕修改其ID為”IDC_BTN_SEND“標(biāo)題為”發(fā)送“。

2、這是一個(gè)基于SOCKET的程序,首先要在CChatApp的IniteInsastance文件中初始加載套接字代碼如下:BOOL CChatApp::InitInstance()
{
?if(!AfxSocketInit())
?{
???? AfxMessageBox("加載套接字庫(kù)失敗");
??return FALSE;
?}。。。。。

其中AfxSocketInit()函數(shù)返回一個(gè)布爾值。要想使用這個(gè)函數(shù)還需要在預(yù)編譯頭文件StdAfx中加入#include”Afxsock.h“

3、緊接著我們?cè)贑ChatDlg中通過(guò)右鍵分別添加一個(gè)成員函數(shù)InitSocket和一個(gè)成員變量m_socket(設(shè)為private)在函數(shù)InitSocket()中添加如下代碼:BOOL CChatDlg::InitSocket()
{
??? m_socket=socket(AF_INET,SOCK_DGRAM,0);
?if(INVALID_SOCKET==m_socket)
?{
???? MessageBox("套接字創(chuàng)建失敗");
??return FALSE;
?} 此段代碼用于創(chuàng)建初始化套接字。緊接著寫(xiě)如下代碼:

SOCKADDR_IN addrSock;
?addrSock.sin_family=AF_INET;
?addrSock.sin_port=htons(6000);
?addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
???
?int retval;
?retval=bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR));
?if(retval==SOCKET_ERROR)
?{
?? closesocket(m_socket);
?? MessageBox("綁定失敗");
?? return FALSE;
?}
?return TRUE;
}此段代碼用于綁定。并在OnInitDialog()中添加聲明InitSocket()。代碼如下:InitSocket();

4、接下來(lái)該接受數(shù)據(jù)啦,我們創(chuàng)建一個(gè)線(xiàn)程專(zhuān)門(mén)用來(lái)接受數(shù)據(jù),并將接受到的數(shù)據(jù)顯示在編輯框中。我應(yīng)該使用線(xiàn)程創(chuàng)建函數(shù)CreateThread()。線(xiàn)程的任務(wù)是接受到數(shù)據(jù)并將其顯示因此需要兩個(gè)參數(shù),注意到CreateThread()函數(shù)的第四個(gè)參數(shù)為結(jié)構(gòu)體指針,因此構(gòu)造一個(gè)結(jié)構(gòu)體,用此結(jié)構(gòu)體傳遞這兩個(gè)參數(shù)。在CChatDlg()中添加一個(gè)結(jié)構(gòu)體構(gòu)造代碼如下:struct RECVPARAM
{
? SOCKET socket;
? HWND hwnd;
};最后這個(gè)雙引號(hào)注意不要丟掉。接著在OnInitDialog()聲明并引用這個(gè)結(jié)構(gòu)體代碼如下:RECVPARAM *pRecvParam=new RECVPARAM;
?pRecvParam->socket=m_socket;
?pRecvParam->hwnd=m_hWnd;//m_hWnd是每個(gè)窗體對(duì)應(yīng)的句柄。

接著在CreateThread()用這個(gè)結(jié)構(gòu)體當(dāng)參數(shù)。代碼如下:

HANDLE hThread=CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);
?CloseHandle(hThread);
?return TRUE;? // return TRUE? unless you set the focus to a control
}上面的這個(gè)函數(shù)CreateThread()的第三個(gè)參數(shù)是對(duì)應(yīng)的是這個(gè)線(xiàn)程的功能函數(shù)RecvProc(要不將此函數(shù)聲明為靜態(tài)的要不將其在全局聲明)。在下面對(duì)此函數(shù)具體實(shí)現(xiàn)編碼如下:

DWORD WINAPI CChatDlg::RecvProc(LPVOID IpParameter)
{
?SOCKET socket=((RECVPARAM*)IpParameter)->socket;
?HWND hwnd=((RECVPARAM*)IpParameter)->hwnd;

?SOCKADDR_IN addrFrom;
?int len=sizeof(SOCKADDR);

?char recvBuf[200];
?char tempBuf[300];
?int retval;
?while(TRUE)
?{
?? retval=recvfrom(socket,recvBuf,200,0,(SOCKADDR*)&addrFrom,&len);
?? if(SOCKET_ERROR==retval)
??? break;
?? sprintf(tempBuf,"%s 說(shuō) %s",inet_ntoa(addrFrom.sin_addr),recvBuf);
??????
?? ::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf);
?}將接受過(guò)來(lái)的數(shù)據(jù)通過(guò)消息響應(yīng)使其顯示到響應(yīng)的編輯框中。編輯代碼步驟如下:

a:在CChatDlg中定義如下:#define WM_RECVDATA WM_USER+1

b:在下面相應(yīng)的地方接著寫(xiě):afx_msg void OnRecvData(WPARAM wParam,LPARAM lParam);

c:在DoDataExchange(CDataExchange *pDx)中寫(xiě)入如下代碼:

BEGIN_MESSAGE_MAP(CChatDlg, CDialog)
?//{{AFX_MSG_MAP(CChatDlg)
?ON_WM_SYSCOMMAND()
?ON_WM_PAINT()
?ON_WM_QUERYDRAGICON()
?ON_BN_CLICKED(IDC_BTN_SEND, OnBtnSend)
?//}}AFX_MSG_MAP
ON_MESSAGE(WM_RECVDATA,OnRecvData)
END_MESSAGE_MAP()

d:

void CChatDlg::OnRecvData(WPARAM wParam,LPARAM lParam)
{
? CString str=(char*)lParam;
? CString strTemp;

? GetDlgItemText(IDC_EDIT_RECV,strTemp);
? str+="/r/n";
? str+=strTemp;
? SetDlgItemText(IDC_EDIT_RECV,str);
}以上四部是一個(gè)消息的過(guò)程。

以上的接受端基本已經(jīng)寫(xiě)好了接下來(lái)該寫(xiě)發(fā)送端啦。

5、雙擊發(fā)送按鈕自動(dòng)生成一個(gè)void CChatDlg::OnBtnSend()函數(shù)其中的代碼如下:

void CChatDlg::OnBtnSend()
{
?// TODO: Add your control notification handler code here
?DWORD dvIp;
?((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dvIp);

?SOCKADDR_IN AddrTo;
?AddrTo.sin_family=AF_INET;
?AddrTo.sin_port=htons(6000);
?AddrTo.sin_addr.S_un.S_addr=htonl(dvIp);

?CString strSend;
?GetDlgItemText(IDC_EDIT_SEND,strSend);
?sendto(m_socket,strSend,strSend.GetLength()+1,0,(SOCKADDR*)&AddrTo,sizeof(SOCKADDR));

?SetDlgItemText(IDC_EDIT_SEND,"");
?
}

以上就是實(shí)現(xiàn)的整個(gè)過(guò)程。

我應(yīng)該對(duì)如下的一些函數(shù)記住:socket()、bind()函數(shù)中具體參數(shù)的含義、句柄handle和hwnd具體含義、CreatThread()函數(shù)以及參數(shù)的具體含義還有其參數(shù)中的功能函數(shù)、sprintf()函數(shù)、afx_msg定義標(biāo)識(shí)符的意義、recvfrom()函數(shù)及參數(shù)、inet_ntoa()函數(shù)功能:將網(wǎng)絡(luò)地址轉(zhuǎn)換成“.”點(diǎn)隔的字符串格式。postMessage()函數(shù):、MV_USER所以自定義消息的步驟:(一)先在頭文件中定義自己消息的ID,如 #define WM_MY_FIRST_MESSAGE (WM_USER + 0x001)   (二)再聲明自己的消息處理函數(shù):afx_msg void OnMyFirstMessage();   (三)在CPP文件中添加消息映射宏: (四)最后定義消息處理函數(shù):

總結(jié)

以上是生活随笔為你收集整理的对做的一个小的C++聊天室的总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。