设为首页 加入收藏

TOP

18.3.3 使用套接字函数设计网络聊天室
2013-10-07 00:13:25 】 浏览:326
Tags:18.3.3 使用 套接字 函数 设计 网络 聊天室

18.3.3  使用套接字函数设计网络聊天室

在18.3.2节中笔者介绍了常用的套接字函数,接下来将利用这些套接字函数设计一个网络聊天室程序。程序由两个实例组成,第1个实例为服务器端,负责接收用户的连接请求,并转发用户信息。第2个实例为客户端,负责连接服务器并发送信息。

服务器端程序设计步骤如下:
ch1806实例位置:mr\18\sl\06
(1)创建一个基于对话框的应用程序,设计对话框资源如图18.11所示。


(2)在对话框的头文件中引用“winsock2.h”头文件,并导入网络库文件。

#include "winsock2.h"
#pragma comment (lib,"ws2_32.lib")

(3)在应用程序的InitInstance方法中初始化套接字。

WSADATA wsd;
WSAStartup(MAKEWORD(2,2),&wsd);

(4)在对话框类中定义成员变量,记录服务器套接字和与之连接的客户端套接字信息。

SOCKET m_server,m_client;
SOCKET m_Clients[MAXNUM];      //客户端套接字
int    m_CurClient;            //当前连接的客户数量

(5)在对话框类的OnInitDialog方法中创建套接字,并初始化数据。

//创建套接字
m_server = socket(AF_INET,SOCK_STREAM,0);
//将网络中的事件关联到窗口的消息函数中
WSAAsyncSelect(m_server,m_hWnd,20000,FD_WRITE|FD_READ|FD_ACCEPT);
m_client = 0;
m_serverIP = "";
for (int i = 0; i< MAXNUM;i++)
m_Clients[i]= 0;
m_CurClient = 0;

(6)处理“监听”按钮的单击事件,将套接字绑定到本机地址,并开始监听套接字。

void CServerDlg::OnOK() 
{
//服务器端地址
sockaddr_in serveraddr;

serveraddr.sin_family = AF_INET;

m_IP.GetWindowText(m_serverIP);

//设置本机地址
serveraddr.sin_addr.S_un.S_addr  = inet_addr(m_serverIP);

UpdateData(TRUE);
//设置端口号
serveraddr.sin_port = htons(m_port);

//绑定地址
if (bind(m_server,(sockaddr*)&serveraddr,sizeof(serveraddr)))
{
MessageBox("绑定地址失败.");
return;
}
//开始监听
listen(m_server,50);
}

(7)向对话框中添加HandleData方法,用于接受客户端的连接,并获得客户端传来的数据,将其转发给其他客户端。

void CServerDlg::HandleData()
{   
sockaddr_in serveraddr;
char buffer[1024];
int len =sizeof(serveraddr);

//接收客户端的数据
int curlink = -1;

int num = -1;
for (int p = 0;p< MAXNUM; p++)
{
num= recv(m_Clients[p],buffer,1024,0);
if (num != -1)
{
curlink = p;
break;
}
}
buffer[num]= 0;
if (num==-1) //接受客户端的连接
{
if (m_CurClient < MAXNUM)
{
m_Clients[m_CurClient] = accept(m_server,(struct sockaddr*)
&serveraddr,&len);
m_CurClient+=1;
}   
return;
}

//将接收的数据发送给客户端
for (int j = 0;j< m_CurClient;j++)
if (j != curlink)
send(m_Clients[j],buffer,num,0);
}

(8)改写对话框类的PreTranslateMessage方法,在服务器套接字中有事件触发时调用HandleData方法。

BOOL CServerDlg::PreTranslateMessage(MSG* pMsg) 
{
if (pMsg->message==20000)
{
HandleData();
return TRUE;
}
else
return CDialog::PreTranslateMessage(pMsg);
}

客户端程序设计步骤如下。
ch1807实例位置:mr\18\sl\07
(1)创建一个基于对话框的工程,设置对话框资源如图18.12所示。

图18.12  客户端设计窗口

(2)在对话框类的头文件中引用“winsock2.h”头文件,并导入“ws2_32.lib”库文件。

#include "winsock2.h"
#pragma comment (lib,"ws2_32.lib")

(3)在应用程序的InitInstance方法中初始化套接字。

WSADATA wsd;
WSAStartup(MAKEWORD(2,2),&wsd);

(4)在对话框的OnInitDialog方法中创建套接字。

m_client = socket(AF_INET,SOCK_STREAM,0);

(5)处理“连接”按钮的单击事件,连接服务器,并设置套接字接收数据时触发的消息。

void CClientDlg::OnOK() 
{
//服务器端地址
sockaddr_in serveraddr;

UpdateData(TRUE);
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(m_port);
serveraddr.sin_addr.S_un.S_addr = inet_addr(m_IP);

if (connect(m_client,(sockaddr*)&serveraddr,sizeof(serveraddr))!=0)
{
MessageBox("连接失败");
return;
}   
else
MessageBox("连接成功");
WSAAsyncSelect(m_client,m_hWnd,1000,FD_READ);
CString str,info ;
m_name.GetWindowText(str);

info.Format("%s------>%s",str,"进入聊天室");
int i = send(m_client,info.GetBuffer(0),info.GetLength(),0);
}

(6)处理“发送”按钮的单击事件,向服务器发送数据。

void CClientDlg::OnButton1() 
{
CString str,name,info ;
m_name.GetWindowText(name);
m_info.GetWindowText(str);
if (!name.IsEmpty()&&!str.IsEmpty())
{
info.Format("%s说: %s",name,str);
//开始发送数据
int i = send(m_client,info.GetBuffer(0),info.GetLength(),0);   
m_list.AddString(info);
m_info.SetWindowText("");
}
}

(7)向对话框类中添加ReceiveData方法,用于接收从服务器传来的数据。

void CClientDlg::ReceiveData(){
char buffer[1024];
//接收服务器端传来的数据,
int num = recv(m_client,buffer,1024,0);
buffer[num] = 0;
//将接收的数据添加到列表框中
m_list.AddString(buffer);
}

(8)改写对话框的PreTranslateMessage方法,截获对话框的消息,用于接收数据。

BOOL CClientDlg::PreTranslateMessage(MSG* pMsg) 
{
if (pMsg->message==1000)
{
ReceiveData();
return TRUE;
}
else
return CDialog::PreTranslateMessage(pMsg);
}

运行程序,效果如图18.13、图18.14、图18.15所示。

图18.13  聊天室服务器

图18.14  客户端窗口1                       

图18.15  客户端窗口2

【责任编辑:阚书 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇18.2.3 获取局域网计算机名称和IP 下一篇18.4.3 使用WinSock类设计网络聊..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目