C++简单QQ程序服务器端的实现代码
本文实例为大家分享了C++简单QQ程序服务器端的实现代码,供大家参考,具体内容如下
//ServerDlg.cpp:implementationfile
//
#include"StdAfx.h"
#include"Server.h"
#include"ServerDlg.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
#defineWM_SHOWTASKWM_USER+1
#defineWM_SERVER_ACCEPTWM_USER+2
/////////////////////////////////////////////////////////////////////////////
//CAboutDlgdialogusedforAppAbout
classCAboutDlg:publicCDialog
{
public:
CAboutDlg();
//DialogData
//{{AFX_DATA(CAboutDlg)
enum{IDD=IDD_ABOUTBOX};
//}}AFX_DATA
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtualvoidDoDataExchange(CDataExchange*pDX);//DDX/DDVsupport
//}}AFX_VIRTUAL
//Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg():CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
voidCAboutDlg::DoDataExchange(CDataExchange*pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
//Nomessagehandlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CServerDlgdialog
CServerDlg::CServerDlg(CWnd*pParent/*=NULL*/)
:CDialog(CServerDlg::IDD,pParent)
{
//{{AFX_DATA_INIT(CServerDlg)
m_strShow=_T("");
//}}AFX_DATA_INIT
//NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32
m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_People=0;
}
voidCServerDlg::DoDataExchange(CDataExchange*pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CServerDlg)
DDX_Control(pDX,IDC_STATIC_PEOPLE,m_strPeople);
DDX_Control(pDX,IDC_STATIC_HOST,m_strHost);
DDX_Text(pDX,IDC_EDIT_SHOW,m_strShow);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CServerDlg,CDialog)
//{{AFX_MSG_MAP(CServerDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_MESSAGE(WM_SHOWTASK,OnShowTask)
ON_MESSAGE(WM_SERVER_ACCEPT,OnServerAccept)
ON_WM_DESTROY()
ON_COMMAND(ID_EXIT,OnDlgExit)
ON_COMMAND(ID_SHOW,OnDlgShow)
ON_COMMAND(ID_HIDE,OnDlgHide)
//}}AFX_MSG_MAP
ON_STN_CLICKED(IDC_STATIC_HOST,&CServerDlg::OnStnClickedStaticHost)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CServerDlgmessagehandlers
BOOLCServerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//Add"About..."menuitemtosystemmenu.
//IDM_ABOUTBOXmustbeinthesystemcommandrange.
ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX<0xF000);
CMenu*pSysMenu=GetSystemMenu(FALSE);
if(pSysMenu!=NULL)
{
CStringstrAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
//Settheiconforthisdialog.Theframeworkdoesthisautomatically
//whentheapplication'smainwindowisnotadialog
SetIcon(m_hIcon,TRUE);//Setbigicon
SetIcon(m_hIcon,FALSE);//Setsmallicon
InitNotify();
SetWindowText("服务器");//在对话框上面显示标题
//1加载Socket库
InitSocket();//2初始化Socket库
returnTRUE;//returnTRUEunlessyousetthefocustoacontrol
}
VOIDCServerDlg::GetHostInfor()
{
charszHostName[128];//获得Shine-PC//存储主机名
if(gethostname(szHostName,128)==0)//正确的情况
{
hostent*pHost;//HostContent
pHost=gethostbyname(szHostName);//网卡信息//pHost返回的是指向主机的列表
LPCSTRpsz=inet_ntoa(*(structin_addr*)pHost->h_addr_list[0]);//得到指向ip的psz变量
CStringstrTemp;
strTemp+="主机名:";
strTemp+=szHostName;
strTemp+="";
strTemp+="IP地址:";
strTemp+=psz;
m_strHost.SetWindowText(strTemp);
CStringstrPeople;
strPeople.Format("%d",m_People);
m_strPeople.SetWindowText(strPeople);
}
}
VOIDCServerDlg::InitSocket()
{
WSADATAwsaData;
WSAStartup(MAKEWORD(2,2),&wsaData);
GetHostInfor();
//创建监听套接字
m_sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(m_sListen==INVALID_SOCKET)
{
MessageBox("CreateSOCKETFailed");
WSACleanup();
return;
}
//初始化网卡
//sockaddr_in(2.2)sockaddr(1.0)
m_ServerAddr.sin_family=AF_INET;
m_ServerAddr.sin_addr.s_addr=INADDR_ANY;
m_ServerAddr.sin_port=htons(9527);
//1.0
//绑定
if(bind(m_sListen,
(sockaddr*)&m_ServerAddr,sizeof(m_ServerAddr))==SOCKET_ERROR)
{
MessageBox("BindFailed");
WSACleanup();
closesocket(m_sListen);
return;
}
//监听
if(listen(m_sListen,20)==SOCKET_ERROR)
{
MessageBox("ListenFailed");
WSACleanup();
closesocket(m_sListen);
return;
}
WSAAsyncSelect(m_sListen,m_hWnd,WM_SERVER_ACCEPT,
FD_ACCEPT|FD_READ|FD_CLOSE);
for(inti=0;i<MAX;i++)
{
m_sClient[i]=INVALID_SOCKET;
}
m_strShow="Nowserverisworking!\r\nWaitingforclient'sconnecting.......";
UpdateData(false);
return;
}
voidCServerDlg::OnSysCommand(UINTnID,LPARAMlParam)
{
if((nID&0xFFF0)==IDM_ABOUTBOX)
{
CAboutDlgdlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID,lParam);
}
}
//Ifyouaddaminimizebuttontoyourdialog,youwillneedthecodebelow
//todrawtheicon.ForMFCapplicationsusingthedocument/viewmodel,
//thisisautomaticallydoneforyoubytheframework.
voidCServerDlg::OnPaint()
{
if(IsIconic())
{
CPaintDCdc(this);//devicecontextforpainting
SendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);
//Centericoninclientrectangle
intcxIcon=GetSystemMetrics(SM_CXICON);
intcyIcon=GetSystemMetrics(SM_CYICON);
CRectrect;
GetClientRect(&rect);
intx=(rect.Width()-cxIcon+1)/2;
inty=(rect.Height()-cyIcon+1)/2;
//Drawtheicon
dc.DrawIcon(x,y,m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//Thesystemcallsthistoobtainthecursortodisplaywhiletheuserdrags
//theminimizedwindow.
HCURSORCServerDlg::OnQueryDragIcon()
{
return(HCURSOR)m_hIcon;
}
VOIDCServerDlg::InitNotify()
{
m_nid.cbSize=sizeof(NOTIFYICONDATA);
m_nid.hWnd=m_hWnd;
m_nid.uID=IDI_ICON_NOTIFY;
m_nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;
m_nid.uCallbackMessage=WM_SHOWTASK;//自定义消息在托盘上处理鼠标动作
m_nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON_NOTIFY));
strcpy(m_nid.szTip,"点我");//当鼠标放在上面时,所显示的内容
Shell_NotifyIcon(NIM_ADD,&m_nid);//在托盘区添加图标
}
LRESULTCServerDlg::OnShowTask(WPARAMwParam,LPARAMlParam)
{
//wParam接收的是图标的ID,而lParam接收的是鼠标的行为
if(wParam!=IDI_ICON_NOTIFY)
{
return1;
}
switch(lParam)
{
caseWM_RBUTTONUP:
{
CMenuMenu;
Menu.CreatePopupMenu();
Menu.AppendMenu(MF_STRING,ID_SHOW,"显示");
Menu.AppendMenu(MF_STRING,ID_HIDE,"隐藏");
Menu.AppendMenu(MF_STRING,ID_EXIT,"退出");
CPointPt;
GetCursorPos(&Pt);//得到鼠标位置
Menu.TrackPopupMenu(TPM_RIGHTBUTTON,Pt.x,Pt.y,this);
Menu.DestroyMenu();//销毁资源
break;
}
}
return0;
}
voidCServerDlg::OnDestroy()
{
CDialog::OnDestroy();
Shell_NotifyIcon(NIM_DELETE,&m_nid);
}
voidCServerDlg::OnDlgExit()
{
SendMessage(WM_CLOSE,NULL,NULL);
}
voidCServerDlg::OnDlgHide()
{
ShowWindow(SW_HIDE);
}
voidCServerDlg::OnDlgShow()
{
::ShowWindow(this->m_hWnd,SW_NORMAL);
}
//FD_ACCEPTFD_CLOSEFD_READ
LRESULTCServerDlg::OnServerAccept(WPARAMwParam,LPARAMlParam)
{
//WSAGETSELECTEVENT==LOWORD(lParam)
intiEvent=WSAGETSELECTEVENT(lParam);
//调用WinsockAPI函数,得到网络事件类型
switch(iEvent)
{
caseFD_ACCEPT://客户端连接请求事件
{
OnAccept();//用户的上线请求Connect
break;
}
caseFD_CLOSE://客户端断开事件:
{
OnClose(wParam);//WParam谁被关闭
break;
}
caseFD_READ://网络数据包到达事件
{
OnRecive(wParam);//Send
break;
}
default:break;
}
return0;
}
VOIDCServerDlg::OnRecive(WPARAMwParam)
{
SENDINFORData={0};
inti=0;
for(i=0;i<MAX;i++)
{
if(m_sClient[i]==wParam)
{
break;
}
}
if(i==MAX)
{
return;
}
intiRet=recv(m_sClient[i],(char*)&Data,sizeof(Data),0);
//0关羽
//消息类型用户名称信息内容
//分析数据包
switch(Data.iType)
{
case20:
case6:
{
//611对方已接受请求,建立连接.......
intj=0;
for(j=0;j<MAX;j++)
{
if(m_sClient[j]!=INVALID_SOCKET&&
strcmp(m_PeopleInfor[j].strName.LockBuffer(),Data.szName)==0)
{
send(m_sClient[j],(char*)&Data,sizeof(Data),0);
}
}
break;
}
case7:
{
intj=0;
for(j=0;j<MAX;j++)
{
if(m_sClient[j]!=INVALID_SOCKET&&
strcmp(m_PeopleInfor[j].strName.LockBuffer(),Data.szName)==0)
{
send(m_sClient[j],(char*)&Data,sizeof(Data),0);
}
}
break;
}
case5://11-12
{
//11--->12
//51211|1.txt|5|
//512192.168.0.100|11|1.txt|5|--->12
CStringstrTemp;
strTemp+=m_PeopleInfor[i].strIp;
strTemp+="|";
strTemp+=Data.szMsg;
strcpy(Data.szMsg,strTemp.LockBuffer());
intj=0;
for(j=0;j<MAX;j++)
{
if(m_sClient[j]!=INVALID_SOCKET&&
strcmp(m_PeopleInfor[j].strName.LockBuffer(),Data.szName)==0)
{
send(m_sClient[j],(char*)&Data,sizeof(Data),0);
}
}
break;
}
case120:
{
intj=0;
for(j=0;j<MAX;j++)
{
if(m_sClient[j]!=INVALID_SOCKET&&
strcmp(m_PeopleInfor[j].strName.LockBuffer(),Data.szName)==0)
{
send(m_sClient[j],(char*)&Data,sizeof(Data),0);
}
}
break;
}
case110:
{
intj=0;
for(j=0;j<MAX;j++)
{
if(m_sClient[j]!=INVALID_SOCKET&&j!=i)
{
send(m_sClient[j],(char*)&Data,sizeof(Data),0);
}
}
break;
}
case2:
{
intj=0;
for(j=0;j<MAX;j++)
{
if(strcmp(m_PeopleInfor[j].strName,Data.szName)==0
&&m_sClient[j]!=INVALID_SOCKET)
{
send(m_sClient[j],(char*)&Data,sizeof(Data),0);
break;
}
}
break;
}
case1:
{
intj=0;
for(j=0;j<MAX;j++)
{
if(m_sClient[j]!=INVALID_SOCKET&&j!=i)
{
send(m_sClient[j],(char*)&Data,sizeof(Data),0);
}
}
break;
}
case0://NewPeople
{
m_PeopleInfor[i].strName=Data.szName;
//向控件添加数据
OnlineOrOutline(i,"上线");
//刷新用户链表
//1向老的通知新的用户(自己得到自己)
intj=0;
for(j=0;j<MAX;j++)
{
if(m_sClient[j]!=INVALID_SOCKET)
{
CStringTemp;
Data.iType=0;
strcpy(Data.szName,m_PeopleInfor[i].strName);
Temp+="\r\n";
GetCurrentTime();
Temp+=m_Timer.LockBuffer();
Temp+="系统消息:\r\n";
Temp+=m_PeopleInfor[i].strName;
Temp+="进入聊天室";
strcpy(Data.szMsg,Temp.LockBuffer());
send(m_sClient[j],(char*)&Data,sizeof(Data),0);
}
}
//向新的通知老的用户
j=0;
for(j=0;j<MAX;j++)
{
if(m_sClient[j]!=INVALID_SOCKET&&j!=i)
{
Data.iType=0;
memset(Data.szMsg,0,400);
strcpy(Data.szName,m_PeopleInfor[j].strName);
send(m_sClient[i],(char*)&Data,sizeof(Data),0);
}
}
break;
}
}
}
VOIDCServerDlg::OnAccept()
{
inti=0;
for(i=0;i<MAX;i++)
{
if(m_sClient[i]==INVALID_SOCKET)
{
break;
}
}
if(i==MAX)
{
return;
}
sockaddr_inClientAddr;
intnLen=sizeof(sockaddr_in);
m_sClient[i]=accept(m_sListen,(sockaddr*)&ClientAddr,&nLen);
LPCSTRstrIP=inet_ntoa(*(structin_addr*)&ClientAddr.sin_addr);
m_PeopleInfor[i].strIp=strIP;
m_People++;
CStringstrPeople;
strPeople.Format("%d",m_People);
m_strPeople.SetWindowText(strPeople);
UpdateData(FALSE);
}
VOIDCServerDlg::GetCurrentTime()
{
SYSTEMTIMEst={0};
GetLocalTime(&st);
intj=0;
j=sprintf(m_Timer.LockBuffer(),"%d年",st.wYear);
j+=sprintf(m_Timer.LockBuffer()+j,"%d月",st.wMonth);
j+=sprintf(m_Timer.LockBuffer()+j,"%d日",st.wDay);
j+=sprintf(m_Timer.LockBuffer()+j,"%d时",st.wHour);
if(st.wMinute<10)
{
inti=0;
j+=sprintf(m_Timer.LockBuffer()+j,"%d",i);
}
j+=sprintf(m_Timer.LockBuffer()+j,"%d分钟",st.wMinute);
if(st.wSecond<10)
{
inti=0;
j+=sprintf(m_Timer.LockBuffer()+j,"%d",i);
}
j+=sprintf(m_Timer.LockBuffer()+j,"%d秒",st.wSecond);
}
VOIDCServerDlg::OnlineOrOutline(intiIndex,CStringYesOrNo)
{
CStringstrTemp;
GetCurrentTime();
strTemp+=m_Timer.LockBuffer();
strTemp+='';
strTemp+="用户:";
strTemp+=m_PeopleInfor[iIndex].strName;
strTemp+="";
strTemp+=m_PeopleInfor[iIndex].strIp;
strTemp+=YesOrNo;
m_strShow+="\r\n";
m_strShow+=strTemp;
UpdateData(FALSE);
}
VOIDCServerDlg::OnClose(WPARAMwParam)
{
inti=0;
for(i=0;i<MAX;i++)
{
if(m_sClient[i]==wParam)
{
break;
}
}
if(i==MAX)
{
return;
}
OnlineOrOutline(i,"下线");
m_People--;
CStringstrPeople;
strPeople.Format("%d",m_People);
m_strPeople.SetWindowText(strPeople);
SENDINFORData;
intj=0;
for(j=0;j<MAX;j++)
{
if(m_sClient[j]!=INVALID_SOCKET&&j!=i)
{
Data.iType=-1;
CStringstrMsg;
GetCurrentTime();
strMsg+=m_Timer.LockBuffer();
strMsg+=m_PeopleInfor[i].strName;
strMsg+="退出了该聊天室";
strcpy(Data.szName,m_PeopleInfor[i].strName.LockBuffer());
strcpy(Data.szMsg,strMsg.LockBuffer());
send(m_sClient[j],(char*)&Data,sizeof(Data),0);
}
}
//清空退出用户的资源
closesocket(m_sClient[i]);
m_sClient[i]=INVALID_SOCKET;
m_PeopleInfor[i].strIp="";
m_PeopleInfor[i].strName="";
}
voidCServerDlg::OnStnClickedStaticHost()
{
//TODO:在此添加控件通知处理程序代码
}
以上就是本文的全部内容,希望对大家的学习有所帮助。