VC++课程设计下了就能用Word格式.docx

上传人:b****8 文档编号:22497262 上传时间:2023-02-04 格式:DOCX 页数:27 大小:225.38KB
下载 相关 举报
VC++课程设计下了就能用Word格式.docx_第1页
第1页 / 共27页
VC++课程设计下了就能用Word格式.docx_第2页
第2页 / 共27页
VC++课程设计下了就能用Word格式.docx_第3页
第3页 / 共27页
VC++课程设计下了就能用Word格式.docx_第4页
第4页 / 共27页
VC++课程设计下了就能用Word格式.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

VC++课程设计下了就能用Word格式.docx

《VC++课程设计下了就能用Word格式.docx》由会员分享,可在线阅读,更多相关《VC++课程设计下了就能用Word格式.docx(27页珍藏版)》请在冰豆网上搜索。

VC++课程设计下了就能用Word格式.docx

CSocket对象提供阻塞模式,这对于Carchive的同步操作是至关重要的。

阻塞函数(如Receive()、Send()、ReceiveFrom()、SendTo()和Accept())直到操作完成后才返回控制权。

三、总体设计

服务器端核心:

等待客户连接;

通知所有在线用户新登录用户信息;

中转消息;

当用户离线时通知所有在线用户。

客户端核心:

获得连接参数后与服务器建立连接;

发送/接收信息;

断开时通知服务器。

模块流程图:

四、详细设计

1.服务器端

(1)新建一个基于对话框的MFC项目,命名为ChatRoom,在接下来的“高级功能”选项卡选择“WindowsSockets”复选框。

(2)在对话框上按照表放置相应的控件。

ID

控件类型

标题

风格/变量

IDC_EDIT_INFO

EditBox

ReadOnly||Multiline||VerticalScroll

IDC_STATIC

GroupBox

在线用户

IDC_LIST_USER

ListBox

CListBoxm_UserList

IDOK

ButtonControl

退出

放置控件后的界面如图服务器端。

(3)添加一个新类,命名为CserverSocket,用于接收客户端的连接。

•ServerSocket.h中的定义如下:

#pragmaonce

#include"

ClientSocket.h"

//CServerSocket命令目标

classCServerSocket:

publicCSocket

{

public:

CPtrListconnectList;

//维护客户端连接的socket链表

CServerSocket();

virtual~CServerSocket();

virtualvoidOnAccept(intnErrorCode);

//服务器接收客户端的连接

};

•ServerSocket.cpp中的实现,这里只重写了OnAccept()函数:

voidCServerSocket:

:

OnAccept(intnErrorCode)

//TODO:

在此添加专用代码和/或调用基类

CClientSocket*clientSocket=newCClientSocket(&

connectList);

//创建socket用于接收客户端连接

Accept(*clientSocket);

//接收新用户连接

clientSocket->

m_parent=(CChatRoomDlg*):

AfxGetMainWnd();

//窗口指针赋值

connectList.AddTail(clientSocket);

//加入到链表尾部

CSocket:

OnAccept(nErrorCode);

}

(4)再添加一个新类,命名为CClientSocket,用于和客户端进行数据交换。

•ClientSocket.h中的定义:

ChatRoomDlg.h"

tagHeader.h"

//CClientSocket命令目标

classCClientSocket:

CStringm_strName;

//连接的用户名

CPtrList*clist;

//与服务器连接的socket链表指针,所有的socket共享

CChatRoomDlg*m_parent;

//维护窗口指针

CClientSocket(CPtrList*list);

//构造函数用于将链表共享

CClientSocket();

virtual~CClientSocket();

virtualvoidOnReceive(intnErrorCode);

//接收到消息的相关处理

virtualvoidOnClose(intnErrorCode);

•ClientSocket.cpp实现

//ClientSocket.cpp:

实现文件

//系统生成的代码略

stdafx.h"

ChatRoom.h"

.\clientsocket.h"

CClientSocket:

CClientSocket(CPtrList*list):

m_parent(NULL)

clist=list;

//链表指针赋值

•CClientSocket成员函数

voidCClientSocket:

OnReceive(intnErrorCode)

charbuff1[sizeof(Header)];

memset(buff1,0,sizeof(buff1));

Receive(buff1,sizeof(buff1));

Header*header=(Header*)buff1;

intlength=header->

len;

chartype=header->

type;

if(type==LOGIN_IO)//将接收到的信息是用户的登录或退出信息

{

charbuff[RECV_LEN];

memset(buff,0,sizeof(buff));

Receive(buff,length);

CTimetime=CTime:

GetCurrentTime();

//得到系统时间

CStringt=time.Format("

%Y-%m-%d%H:

%M:

%S"

);

//格式化成字符串

CEdit*p_Edit=(CEdit*):

AfxGetMainWnd()->

GetDlgItem(IDC_EDIT_INFO);

CStringstrTemp=t+"

"

+CString(buff)+"

进入聊天室...\r\n"

;

p_Edit->

ReplaceSel(strTemp);

//在界面上显示

m_strName=buff;

//用户名赋值

m_parent->

UpdateUser(this);

}

if(type==SEND_MESSAGE)//将要接收的信息是用户发送的信息

charbuf[RECV_LEN];

memset(buf,0,sizeof(buf));

Receive(buf,sizeof(buf));

//接收信息

CClientSocket*curr=NULL;

POSITIONpos=clist->

GetHeadPosition();

while(pos!

=NULL)//发送给每一个在线用户

{

curr=(CClientSocket*)clist->

GetNext(pos);

curr->

Send((char*)header,sizeof(Header));

Send(buf,sizeof(buf));

}

OnReceive(nErrorCode);

OnClose(intnErrorCode)

Find(this);

//找到要退出的Socket对象

if(pos!

=NULL)

clist->

RemoveAt(pos);

//移除

//得到时间等信息再在界面上显示

+this->

m_strName+"

离开聊天室\r\n"

//把退出用户从界面上移掉

this->

Close();

//Socket对象关闭

deletethis;

OnClose(nErrorCode);

(5)用到的头文件tagHeader.h是这样定义的(后面的客户端也会用到):

typedefstructtagHeader

chartype;

intlen;

}Header,*pHeader;

//发送的信息头

constintSERVER_PORT=9999;

//服务器监听端口

constintLOGIN_IO=1;

//登录或退出标记

constintSEND_MESSAGE=3;

//发送信息标记

constintRECV_LEN=256;

//接收信息长度

constintCLIENT_NUM=50;

//聊天室的人数上线

(6)下面是服务器的初始化代码:

BOOLCChatRoomDlg:

OnInitDialog()

//系统自动生成的代码略

在此添加额外的初始化代码

CServerSocket*m_pSocket;

m_pSocket=newCServerSocket;

if(!

m_pSocket->

Create(SERVER_PORT))//创建服务器的监听Socket

AfxMessageBox("

创建socket失败!

"

returnFALSE;

Listen())//监听

监听发生错误!

((CEdit*)GetDlgItem(IDC_EDIT_INFO))->

ReplaceSel("

服务器初始化成功...\r\n"

//界面显示

returnTRUE;

//除非设置了控件的焦点,否则返回TRUE

(7)用户登录或者退出时界面上的显示:

//用户的更新,包括用户登录和退出等

voidCChatRoomDlg:

UpdateUser(CClientSocket*pSocket)

CStringuser_name;

//用户名字符串

if(pSocket!

m_UserList.ResetContent();

//清空过时内容

CClientSocket*pSock=NULL;

POSITIONpos=pSocket->

clist->

//取得socket链表头

while(pos!

=NULL)//在界面上显示每一个在线用户

pSock=(CClientSocket*)pSocket->

//只要链表不空,依次取下一个位置

m_UserList.AddString(pSock->

m_strName);

//显示

user_name+=(pSock->

&

Headerhead;

//信息头

head.type=LOGIN_IO;

//本信息是用户登录或退出信息

head.len=user_name.GetLength();

POSITIONpo=pSocket->

while(po!

=NULL)//向其他的在线用户发送新用户登录信息

GetNext(po);

pSock->

Send((char*)&

head,sizeof(Header));

//发送信息头

Send((LPCTSTR)user_name,user_name.GetLength());

//发送新用户的名字

2.客户端

(1)添加一个基于对话框的MFC项目,命名为ChatClient,同样要在“高级功能”选项卡选择“WindowsSockets”复选框。

(2)在对话框上放置如表控件。

聊天信息

IDC_EDIT_LIST

Mutiline||VerticalScroll

CEditm_MessageList;

在线列表

IDC_EDIT_MESSAGE

CStringm_strMessage

ID_SEND

发送

DefaultButton

放置好控件的界面如图客户端所示。

注意:

去掉“退出”按钮缺省属性,给“发送”设置缺省属性。

(3)考虑到用户登录时需要添加诸如服务器地址,自己的用户名等信息,我们需要再加入一个对话框资源,命名为IDD_DIALOG_LOGIN,并为该对话框添加类CLoginDlg(基类是CDialog),然后再对话框上按照表放置以下控件。

登录

StaticText

昵称:

服务器IP:

IDC_EDIT_NAME

CStringm_strName

IDC_EDIT_SERVER

CStringm_strServer

放置控件后的界面如下图所示。

(4)在ChatClient项目中仍然需要一个Socket类CClientSocket来完成数据的发送和接受,具体封装和ChatRoom项目中的CClientSocket封装类似(也可以拷贝并加入到ChatClient项目中修改),下面是具体的封装:

classCChatClientDlg;

CChatClientDlg*chatDlg;

//窗口指针,便于在界面上显示信息

•ClientSocket.cpp中的实现:

//CClientSocket成员函数

{//根据type字段决定是接收信息或者是用户登录/退出消息

charbuf[sizeof(Header)];

//用于接收消息头的缓冲区

memset(buf,0,sizeof(buf));

Receive(buf,sizeof(buf));

//接收消息头

Header*header=(Header*)buf;

//强制转换成消息头结构

if(type==SEND_MESSAGE)//发送的是信息

chatDlg->

GetMessage();

if(type==LOGIN_IO)//是用户登录/退出消息

UpdateUser();

//处理用户登录或退出消息

(5)因为在两个对话框(即“登录”对话框和主聊天对话框)中都用到同一个Socket对象,所以有必要在CChatClientApp主程序中定义一个全局的客户端Socket对象,同时修改两个对话框的构造函数,具体如下:

•ClientSocket.h中对CClientSocket类的定义:

ChatClient.h"

ChatClientDlg.h"

•CLoginDlg构造函数的改写:

为了便于本地测试,程序默认服务器IP地址为本地IP地址。

//CLoginDlg对话框

IMPLEMENT_DYNAMIC(CLoginDlg,CDialog)

CLoginDlg:

CLoginDlg(CClientSocket*p_Socket,CWnd*pParent/*=NULL*/)

:

CDialog(CLoginDlg:

IDD,pParent)

m_strName(_T("

))

m_strServer(_T("

//获取本地IP地址并默认指示为服务器IP

{

charHostName[128];

structhostent*pHost;

CStringstr;

if(gethostname(HostName,128)==0)

pHost=gethostbyname(HostName);

for(inti=0;

pHost!

=NULL&

pHost->

h_addr_list[i]!

=NULL;

++i)

str=inet_ntoa(*(structin_addr*)pHost->

h_addr_list[i]);

m_pSocket=p_Socket;

m_strServer=str;

str.Empty();

•CChatClientDlg构造函数的改写:

//CChatClientDlg对话框

CChatClientDlg:

CChatClientDlg(CClientSocket*p_Socket,CWnd*pParent/*=NULL*/)

CDialog(CChatClientDlg:

m_strMessage(_T("

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 其它

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1