C++课程设计基于Socket通信的聊天室Word格式文档下载.docx
《C++课程设计基于Socket通信的聊天室Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《C++课程设计基于Socket通信的聊天室Word格式文档下载.docx(19页珍藏版)》请在冰豆网上搜索。
![C++课程设计基于Socket通信的聊天室Word格式文档下载.docx](https://file1.bdocx.com/fileroot1/2022-10/11/f4892262-828f-491d-b6cb-eedd61bbaf9f/f4892262-828f-491d-b6cb-eedd61bbaf9f1.gif)
因此本次毕业设计以“面向连接的Winsock网络会话程序开发”为题,制作一个C/S聊天室程序,通过制作该程序还能更好的学习网络socket编程的相关知识。
1.2聊天室的设计目标
本课题是建立聊天通信模型,设计一个聊天室软件,只是简单的利用Socket来实现端到端的通信,主要功能为:
服务器端功能:
1、初始化socket,进行单对单的点对点连接模式
2、输入远程用户的IP地址可以进行socket连接。
3、接受用户传送来的聊天信息,然后显示在列表上。
4、接受用户传送来的连接判断命令,并向用户发出响应命令。
2.总体设计
2.1功能要求
支持点到点的连接,在服务器和多个客户端之间进行数据传输;
接收客户端发送的消息,并显示在一个列表框中;
显示出连接的用户计算机名字;
2.2系统主要功能和主要功能描述:
聊天程序必须能够做3件事情:
(1)聊天程序要在待定的端口上通过socket发送聊天文字,并发送到开启相同程序的客
户端。
(2)聊天程序要及时接受从其他地方发送过来的信息,然后把这些信息显示在列表框中
去。
(3)服务器还要监控这些连接的状态,在客户主动离开或发生故障时从列表中删除相应
的表项,并及时更新连接表。
这些要求可以通过CSocket类提供的功能实现。
从CSocket派生出两个类CListenSocket和CClientSocket,它们分别用来侦听客户的连接请求和建立与客户的连接。
服务器只需要一个侦听套接字CListenSocket,然后根据客户的连接请求动态创建客户套接字CClientSocket。
客户套接字的数量是不可预知的,因此需要一个列表来记录。
MFC的CPtrList类就能实现这种功能。
3.详细设计
3.1设计流程图
CClientSocketCClientSocket
启动启动
登陆成功
连接上创建子套接字客户端用户
发送message
显
示
找到客户端并显示
MessageMessage
3.2设计实现
(1)首先启动VisualC++6.0,利用MFCAppWizard[EXE]建立一个新的MFC工程,工程名为tcpclient,在MFCAppWizardStep1的时候选择Dialogbased即基于对话框,在Step4时勾选WindowsSockets选项(如图3-11),其他默认值下一步。
图3-11
(2)程序主要分为三个窗口,第一个是发送数据的窗口,需要输入连接到服务器的相关设置信息,一般为IP地址,第二个是聊天信息显示窗口,也就是接受数据的窗口,该窗口显示接收到的消息;
第三个是消息编辑发送窗口,需要输入你要发送的信息内容并发送,还有一个是主机名窗口,输入目标的主机名即可发送信息。
图3-12
(3)下面重点介绍一下单击连接服务器按钮时的处理网络连接的函数。
代码设置如下:
BOOLCChatRoomDlg:
:
OnInitDialog()
{
CDialog:
OnInitDialog();
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);
AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
//Settheiconforthisdialog.Theframeworkdoesthisautomatically
//whentheapplication'
smainwindowisnotadialog
SetIcon(m_hIcon,TRUE);
//Setbigicon
SetIcon(m_hIcon,FALSE);
//Setsmallicon
//TODO:
Addextrainitializationhere
InitSocket();
returnTRUE;
//returnTRUEunlessyousetthefocustoacontrol
(5)接下来就是创建通信隧道,绑定监听端口的函数,代码设置如下:
HCURSORCChatRoomDlg:
OnQueryDragIcon(){
return(HCURSOR)m_hIcon;
InitSocket(){
m_socket=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,0);
if(INVALID_SOCKET==m_socket)
MessageBox("
创建套接字失败"
);
returnFALSE;
SOCKADDR_INaddrSock;
addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSock.sin_family=AF_INET;
addrSock.sin_port=htons(6000);
if(SOCKET_ERROR==bind(m_socket,(SOCKADDR*)&
addrSock,
sizeof(SOCKADDR)))
绑定失败"
if(SOCKET_ERROR==WSAAsyncSelect(m_socket,m_hWnd,UM_SOCK,FD_READ))
注册网络读取事件失败"
通过WSASocket()函数,来创建socket套接字建立通信隧道,再用htons来绑定本机
的6000端口,即监听端口。
(6)要显示客户端接收到来自其他用户的信息,代码设置如下:
voidCChatRoomDlg:
OnSock(WPARAMwParam,LPARAMlParam)
switch(LOWORD(lParam))
caseFD_READ:
WSABUFwsabuf;
wsabuf.buf=newchar[200];
wsabuf.len=200;
DWORDdwRead;
DWORDdwFlag=0;
SOCKADDR_INaddrFrom;
intlen=sizeof(SOCKADDR);
CStringstr,strTemp;
HOSTENT*pHost;
if(SOCKET_ERROR==WSARecvFrom(m_socket,&
wsabuf,1,&
dwRead,&
dwFlag,
(SOCKADDR*)&
addrFrom,&
len,NULL,NULL))
接收数据失败"
return;
pHost=gethostbyaddr((char
*)&
addrFrom.sin_addr.S_un.S_addr,4,AF_INET);
//str.Format("
%s说:
%s"
inet_ntoa(addrFrom.sin_addr),wsabuf.buf);
str.Format("
pHost->
h_name,wsabuf.buf);
str+="
\r\n"
;
GetDlgItemText(IDC_EDIT_RECV,strTemp);
str+=strTemp;
SetDlgItemText(IDC_EDIT_RECV,str);
break;
设计步骤:
接受来自服务器套接字的信息数据保存到addrFrom中,调整格式后将其打印到消息
区。
(7)当本地程序发送信息时调用的功能函数。
OnBtnSend()
Addyourcontrolnotificationhandlercodehere
DWORDdwIP;
CStringstrSend;
DWORDdwSend;
intlen;
CStringstrHostName;
SOCKADDR_INaddrTo;
if(GetDlgItemText(IDC_EDIT_HOSTNAME,strHostName),strHostName=="
"
)
((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->
GetAddress(dwIP);
addrTo.sin_addr.S_un.S_addr=htonl(dwIP);
else
pHost=gethostbyname(strHostName);
addrTo.sin_addr.S_un.S_addr=*((DWORD*)pHost->
h_addr_list[0]);
addrTo.sin_family=AF_INET;
addrTo.sin_port=htons(6000);
GetDlgItemText(IDC_EDIT_SEND,strSend);
len=strSend.GetLength();
wsabuf.buf=strSend.GetBuffer(len);
wsabuf.len=len+1;
SetDlgItemText(IDC_EDIT_SEND,"
if(SOCKET_ERROR==WSASendTo(m_socket,&
dwSend,0,(SOCKADDR
addrTo,sizeof(SOCKADDR),NULL,NULL))
发送数据失败"
return;
4.系统调试
在本地编译-组建-运行后的结果,如图4-1所示:
图4-1
在远程一台客户端运行同样的程序,在两台