VC学习笔记11尝试互联网
来源:互联网 发布:win10 python环境搭建 编辑:程序博客网 时间:2024/05/16 07:59
下面以聊天室为例,来解析网络编程代码
聊天软件由服务器端和客户端两部分组成,先来说下服务器端
在VC++6.0环境下,建立MFC对话框工程,我这里的工程名为hlw
在对话框类CHlwDlg所在文件下先加入
#include "winsock2.h"
#pragma comment (lib,"ws2_32.lib")
#define MAXNUM 10
第一个是需要的头文件,下面调入静态链接库,后面的宏定义是最大连接数
下面再该类的声名中加入几个变量
public:
void TranslateData(); //声明事件响应函数
SOCKET m_SockServer; //用在服务器端的监听套接字
SOCKET m_Clients[MAXNUM]; //定义套接字数组用于为每个客户端进行连接
SOCKET m_SockClient; //定义用于客户端的临时套接字变量
int m_ConnectNum; //表示连接个数
CString m_IP; //ip地址
UINT m_Port; //端口号
那么SOCKET是一个什么数据类型呢?
typedef u_int SOCKET; //这个是原定义unsigned int
在网络协议中我们用套接字来唯一标识网络中的进程,这也是个ID
当然,在网络编程中必须先启动套接字
在CHlwApp类中的InitInstance()响应中加入启动函数
WSADATA wsd; //启用winsock
WSAStartup(MAKEWORD(2,2),&wsd); //启动套接字
在应用结束方法ExitInstance()中加入关闭套接字函数
WSACleanup(); //清除套接字
下面我们建立两个编辑框,并且为他们关联两个变量
m_editip //ip地址编辑
m_editport //端口编辑
添加一个设置按钮
下面是响应函数
void CHlwDlg::OnOK()
{
m_editip.GetWindowText(m_IP); //将ip编辑窗口上的内容给m_IP
CString strport; //定义临时字符串储存变量
m_editport.GetWindowText(strport); //将端口编辑窗ko上的内容给strport
if(m_IP.IsEmpty()||strport.IsEmpty()) //如果为空弹出错误信息
{
MessageBox("设置错误","错误");return;
}
m_Port=atoi(strport); //转换成int
sockaddr_in serveraddr; //定义套接字地址信息变量
serveraddr.sin_family=AF_INET; //下面进行设置
serveraddr.sin_addr.S_un.S_addr=inet_addr(m_IP); //配置IP这里的输入为字符串类型,所以要转化成一个特定的量
serveraddr.sin_port=htons(m_Port); //设置端口,这边输入是int型,所以用htons转换
if(bind(m_SockServer,(sockaddr*)&serveraddr,sizeof(serveraddr))) //绑定套接字,用服务器端的地址信息
{
MessageBox("绑定地址失败"); return;
}
listen(m_SockServer,20); //监听客户端建立连接的套接字
}
当点击设置按钮,就会配置好服务器的IP和端口。
IP是每台电脑的标识,端口是某台电脑某个应用程序的标识。
启动监听后,该程序就会响应网络中的信息
那么如何响应
在对话框创建过程中
BOOL CHlwDlg::OnInitDialog()
{
CDialog::OnInitDialog();
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// 下面是加上的内容
m_SockServer=socket(AF_INET,SOCK_STREAM,0); //创建套接字
WSAAsyncSelect(m_SockServer,m_hWnd,WM_USER+1,FD_WRITE|FD_READ|FD_ACCEPT);
//关联套接字中的FD_WRITE|FD_READ|FD_ACCEPT信息到消息WM_USER+1中(前面有定义)
m_ConnectNum=0; //连接数为0
for(int i=0;i<MAXNUM;i++) //初始化
m_Clients[i]=0;
return TRUE;
}
该过程用自定义响应WM_USER+1来处理每次监听到网络中的信息
#define WM_USER 0x0400
可以看到WM_USER是已经被系统定义过的
我们在这处地方加上响应声明:
BEGIN_MESSAGE_MAP(CHlwDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//下面这个是加入的
ON_MESSAGE(WM_USER+1,TranslateData) //用TranslateData作为WM_USER+1的响应函数
将WM_USER+1这个响应绑定到函数TranslateData中
下面来看下这个函数
void CHlwDlg::TranslateData()
{
sockaddr_in serveraddr; //定义套接字地址配置变量,用来配置所要发送给谁的信息
char buffer[1024]; //定义接收缓冲区
int len=sizeof(serveraddr);
int curlink=-1; //保存当前的连接位置
int num=-1;
for(int i=0;i<MAXNUM;i++) //轮流察看是否接收到信息
{
num=recv(m_Clients[i],buffer,1024,0); //如果没有接收到数据,则是接收到客户端连接
if(num!=-1)
{
curlink=i;
break;
}
}
buffer[num]=0;
if(num==-1) //接收客户端连接,连接是在第一次
{
if(m_ConnectNum<MAXNUM)
{
m_Clients[m_ConnectNum]=accept(m_SockServer,(struct sockaddr*)&serveraddr,&len); //接受接收到的套接字请求,保存
m_ConnectNum++; //连接数+1
}
return;
}
for(int j=0;j<m_ConnectNum;j++) //对于除发送方外的其他客户端广播,这里只将接受到的数据直接转发
{
if(j!=curlink)
send(m_Clients[j],buffer,num,0);
}
}
下面是客户端的程序:
首先和服务端一样:
创建实例时:
int CKhdApp::ExitInstance()
{
WSACleanup(); //释放套接字
return CWinApp::ExitInstance();
}
退出实例加上
WSACleanup(); //释放套接字
在对话框上先加入三个编辑器
分别分配变量为:
m_ServerIP //输入的服务器IP地址
m_ServerPort //输入服务器的端口
m_NickName //昵称
再加上一个登录按钮
后面,加入列表控件作为信息显示部分
为其分配变量为
m_MsgList
再在下面加入编辑器作为发送信息的临时储存内容
为其分配变量为
m_SendData
在对话框类的文件中先定义
#include "winsock2.h"
#pragma comment (lib,"ws2_32.lib")
#define CM_RECEIVE 1000 //这个表示一个ID号
然后再声明
void ReceiveInfo(); //用来处理网络响应
CString m_IP; //ip地址
UINT m_Port; //端口号
SOCKET m_SockClient; //定义用于客户端的套接字变量
现在处理登录按钮
void CKhdDlg::OnButton1()
{
sockaddr_in serveraddr; //定义套接字信息
CString strport;
m_ServerPort.GetWindowText(strport);
m_ServerIP.GetWindowText(m_IP);
if(strport.IsEmpty()|m_IP.IsEmpty())
{
MessageBox("服务器或端口号错误");
return;
}
m_SockClient=socket(AF_INET,SOCK_STREAM,0); //这个应该是用来获取本地网络的信息吧
m_Port=atoi(strport);
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_SockClient,(sockaddr*)&serveraddr,sizeof(serveraddr))!=0) //连接
{
MessageBox("连接失败");
return;
}
else
MessageBox("连接成功");
WSAAsyncSelect(m_SockClient,m_hWnd,CM_RECEIVE,FD_READ); //建立网络事件通知机制
CString strname,info;
m_NickName.GetWindowText(strname);
info.Format("%s----->%s",strname,"进入聊天室");
send(m_SockClient,info.GetBuffer(0),info.GetLength(),0); //发送到网络,当然,互联网上的信息都是广播
}
下面在事件声明下面加入
ON_MESSAGE(CM_RECEIVE,ReceiveInfo) //将CM_RECEIVE事件的响应函数定义为ReceiveInfo()
下面是事件处理函数
void CKhdDlg::ReceiveInfo()
{
char buffer[1024];
int num=recv(m_SockClient,buffer,1024,0);
buffer[num]=0;
m_MsgList.AddString(buffer); //列表控件插入字符
}
下面实现发送按钮
void CKhdDlg::OnButton2()
{
CString strData,name,info;
m_NickName.GetWindowText(name);
m_SendData.GetWindowText(strData);
if(!name.IsEmpty()&&!strData.IsEmpty())
{
info.Format("%s说:%s",name,strData); //格式化字符串
send(m_SockClient,info.GetBuffer(0),info.GetLength(),0); //把字符串广播出去
m_MsgList.AddString(info);
m_SendData.SetWindowText("");
}
}
当然,这边的客户端发送信息都是可以被任何网络上的设备监听到的,
这时就需要数据加密了。
聊天软件由服务器端和客户端两部分组成,先来说下服务器端
在VC++6.0环境下,建立MFC对话框工程,我这里的工程名为hlw
在对话框类CHlwDlg所在文件下先加入
#include "winsock2.h"
#pragma comment (lib,"ws2_32.lib")
#define MAXNUM 10
第一个是需要的头文件,下面调入静态链接库,后面的宏定义是最大连接数
下面再该类的声名中加入几个变量
public:
void TranslateData(); //声明事件响应函数
SOCKET m_SockServer; //用在服务器端的监听套接字
SOCKET m_Clients[MAXNUM]; //定义套接字数组用于为每个客户端进行连接
SOCKET m_SockClient; //定义用于客户端的临时套接字变量
int m_ConnectNum; //表示连接个数
CString m_IP; //ip地址
UINT m_Port; //端口号
那么SOCKET是一个什么数据类型呢?
typedef u_int SOCKET; //这个是原定义unsigned int
在网络协议中我们用套接字来唯一标识网络中的进程,这也是个ID
当然,在网络编程中必须先启动套接字
在CHlwApp类中的InitInstance()响应中加入启动函数
WSADATA wsd; //启用winsock
WSAStartup(MAKEWORD(2,2),&wsd); //启动套接字
在应用结束方法ExitInstance()中加入关闭套接字函数
WSACleanup(); //清除套接字
下面我们建立两个编辑框,并且为他们关联两个变量
m_editip //ip地址编辑
m_editport //端口编辑
添加一个设置按钮
下面是响应函数
void CHlwDlg::OnOK()
{
m_editip.GetWindowText(m_IP); //将ip编辑窗口上的内容给m_IP
CString strport; //定义临时字符串储存变量
m_editport.GetWindowText(strport); //将端口编辑窗ko上的内容给strport
if(m_IP.IsEmpty()||strport.IsEmpty()) //如果为空弹出错误信息
{
MessageBox("设置错误","错误");return;
}
m_Port=atoi(strport); //转换成int
sockaddr_in serveraddr; //定义套接字地址信息变量
serveraddr.sin_family=AF_INET; //下面进行设置
serveraddr.sin_addr.S_un.S_addr=inet_addr(m_IP); //配置IP这里的输入为字符串类型,所以要转化成一个特定的量
serveraddr.sin_port=htons(m_Port); //设置端口,这边输入是int型,所以用htons转换
if(bind(m_SockServer,(sockaddr*)&serveraddr,sizeof(serveraddr))) //绑定套接字,用服务器端的地址信息
{
MessageBox("绑定地址失败"); return;
}
listen(m_SockServer,20); //监听客户端建立连接的套接字
}
当点击设置按钮,就会配置好服务器的IP和端口。
IP是每台电脑的标识,端口是某台电脑某个应用程序的标识。
启动监听后,该程序就会响应网络中的信息
那么如何响应
在对话框创建过程中
BOOL CHlwDlg::OnInitDialog()
{
CDialog::OnInitDialog();
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// 下面是加上的内容
m_SockServer=socket(AF_INET,SOCK_STREAM,0); //创建套接字
WSAAsyncSelect(m_SockServer,m_hWnd,WM_USER+1,FD_WRITE|FD_READ|FD_ACCEPT);
//关联套接字中的FD_WRITE|FD_READ|FD_ACCEPT信息到消息WM_USER+1中(前面有定义)
m_ConnectNum=0; //连接数为0
for(int i=0;i<MAXNUM;i++) //初始化
m_Clients[i]=0;
return TRUE;
}
该过程用自定义响应WM_USER+1来处理每次监听到网络中的信息
#define WM_USER 0x0400
可以看到WM_USER是已经被系统定义过的
我们在这处地方加上响应声明:
BEGIN_MESSAGE_MAP(CHlwDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//下面这个是加入的
ON_MESSAGE(WM_USER+1,TranslateData) //用TranslateData作为WM_USER+1的响应函数
将WM_USER+1这个响应绑定到函数TranslateData中
下面来看下这个函数
void CHlwDlg::TranslateData()
{
sockaddr_in serveraddr; //定义套接字地址配置变量,用来配置所要发送给谁的信息
char buffer[1024]; //定义接收缓冲区
int len=sizeof(serveraddr);
int curlink=-1; //保存当前的连接位置
int num=-1;
for(int i=0;i<MAXNUM;i++) //轮流察看是否接收到信息
{
num=recv(m_Clients[i],buffer,1024,0); //如果没有接收到数据,则是接收到客户端连接
if(num!=-1)
{
curlink=i;
break;
}
}
buffer[num]=0;
if(num==-1) //接收客户端连接,连接是在第一次
{
if(m_ConnectNum<MAXNUM)
{
m_Clients[m_ConnectNum]=accept(m_SockServer,(struct sockaddr*)&serveraddr,&len); //接受接收到的套接字请求,保存
m_ConnectNum++; //连接数+1
}
return;
}
for(int j=0;j<m_ConnectNum;j++) //对于除发送方外的其他客户端广播,这里只将接受到的数据直接转发
{
if(j!=curlink)
send(m_Clients[j],buffer,num,0);
}
}
下面是客户端的程序:
首先和服务端一样:
创建实例时:
int CKhdApp::ExitInstance()
{
WSACleanup(); //释放套接字
return CWinApp::ExitInstance();
}
退出实例加上
WSACleanup(); //释放套接字
在对话框上先加入三个编辑器
分别分配变量为:
m_ServerIP //输入的服务器IP地址
m_ServerPort //输入服务器的端口
m_NickName //昵称
再加上一个登录按钮
后面,加入列表控件作为信息显示部分
为其分配变量为
m_MsgList
再在下面加入编辑器作为发送信息的临时储存内容
为其分配变量为
m_SendData
在对话框类的文件中先定义
#include "winsock2.h"
#pragma comment (lib,"ws2_32.lib")
#define CM_RECEIVE 1000 //这个表示一个ID号
然后再声明
void ReceiveInfo(); //用来处理网络响应
CString m_IP; //ip地址
UINT m_Port; //端口号
SOCKET m_SockClient; //定义用于客户端的套接字变量
现在处理登录按钮
void CKhdDlg::OnButton1()
{
sockaddr_in serveraddr; //定义套接字信息
CString strport;
m_ServerPort.GetWindowText(strport);
m_ServerIP.GetWindowText(m_IP);
if(strport.IsEmpty()|m_IP.IsEmpty())
{
MessageBox("服务器或端口号错误");
return;
}
m_SockClient=socket(AF_INET,SOCK_STREAM,0); //这个应该是用来获取本地网络的信息吧
m_Port=atoi(strport);
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_SockClient,(sockaddr*)&serveraddr,sizeof(serveraddr))!=0) //连接
{
MessageBox("连接失败");
return;
}
else
MessageBox("连接成功");
WSAAsyncSelect(m_SockClient,m_hWnd,CM_RECEIVE,FD_READ); //建立网络事件通知机制
CString strname,info;
m_NickName.GetWindowText(strname);
info.Format("%s----->%s",strname,"进入聊天室");
send(m_SockClient,info.GetBuffer(0),info.GetLength(),0); //发送到网络,当然,互联网上的信息都是广播
}
下面在事件声明下面加入
ON_MESSAGE(CM_RECEIVE,ReceiveInfo) //将CM_RECEIVE事件的响应函数定义为ReceiveInfo()
下面是事件处理函数
void CKhdDlg::ReceiveInfo()
{
char buffer[1024];
int num=recv(m_SockClient,buffer,1024,0);
buffer[num]=0;
m_MsgList.AddString(buffer); //列表控件插入字符
}
下面实现发送按钮
void CKhdDlg::OnButton2()
{
CString strData,name,info;
m_NickName.GetWindowText(name);
m_SendData.GetWindowText(strData);
if(!name.IsEmpty()&&!strData.IsEmpty())
{
info.Format("%s说:%s",name,strData); //格式化字符串
send(m_SockClient,info.GetBuffer(0),info.GetLength(),0); //把字符串广播出去
m_MsgList.AddString(info);
m_SendData.SetWindowText("");
}
}
当然,这边的客户端发送信息都是可以被任何网络上的设备监听到的,
这时就需要数据加密了。
0 0
- VC学习笔记11尝试互联网
- vc++ 学习笔记11
- 互联网营销学习笔记
- 互联网协议学习笔记
- 计算机网络和互联网学习笔记
- 2007-11-7 VC学习笔记
- VC++学习笔记1
- VC++学习笔记2
- VC学习笔记
- VC++ 学习笔记(-)
- VC++ 学习笔记(二)
- VC++学习笔记(三)
- VC++学习笔记(四)
- vc++学习笔记(五)
- VC++7学习笔记
- VC学习笔记
- VC++学习笔记
- VC学习笔记
- error C4430: 缺少类型说明符 - 假定为 int
- iOS 7 导航 路线
- 使用Xcode和Instruments调试解决iOS内存泄露
- KMP字符串匹配算法
- scp - SSH远程文件/目录传输命令
- VC学习笔记11尝试互联网
- 深入理解maven及应用
- UIAlertView 按钮设置可点或者不可点击
- Linux进程间通信——使用流套接字
- 电商商家后台-easyUI的combox三级联动
- iOS中几种数据持久化方案
- OpenDaylight峰会SDN进步案例演变
- 推荐大家使用的CSS书写规范
- Linux 命令汇总