这是上个学期网络通讯的课程设计所做的作业,C++语言中的MFC写的。
后面将更新C#版本的基于socket的程序。废话不多说mfc socket onclose,直接上源码:

服务端代码:
// sFileDlg.cpp : 实现文件
//
#include <winsock2.h>
#include "stdafx.h"
#include "sFile.h"
#include "sFileDlg.h"
#include "afxdialogex.h"
#pragma comment(lib, "WS2_32.lib")
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
UINT server_thd(LPVOID p); //声明线程函数
SOCKET listen_sock;//定义一个全局的soket
SOCKET sock;//定义一个soket
CString showeditmsg; //定义全局的显示消息的字符串
// CsFileDlg 对话框
CsFileDlg::CsFileDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CsFileDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CsFileDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CsFileDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BtnSend, &CsFileDlg::OnBnClickedBtnsend)
amp-21-c-500 smt3000cs smt-3000-s-30-2.5 smr-3106-s-30-2.5 txtp5 rxtp5 amp-21c-500。l=11&,全程约23,4832033&,经过10站,1&:地铁2号线 → 地铁4号线大兴线.6公里。c=13510513,3636478.615&.2%2c3636497,1&, 到达虹桥2号航站楼站。
END_MESSAGE_MAP()
// CsFileDlg 消息处理程序
BOOL CsFileDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作

SetIcon(m_hIcon, TRUE);// 设置大图标
SetIcon(m_hIcon, FALSE);// 设置小图标
// TODO: 在此添加额外的初始化代码
show_edit = (CEdit *)GetDlgItem(IDC_EDIT1);
send_edit = (CEdit *)GetDlgItem(IDC_EDIT2);
port_edit = (CEdit *)GetDlgItem(IDC_EDIT3);
star_btn = (CButton *)GetDlgItem(IDC_BUTTON2);
showmsg_edit = (CEdit *)GetDlgItem(IDC_EDIT4);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CsFileDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CsFileDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
//添加函数update() 更新消息数据

void CsFileDlg::update(CString s)
{
showeditmsg += s;
show_edit->SetWindowText(showeditmsg);
}
//开启服务器按钮响应事件
void CsFileDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
WSADATA wsData;
WSAStartup(MAKEWORD(2,2), &wsData);
char name[80];
CString IP;
CString P;
hostent* pHost;
gethostname(name,sizeof(name));//获得主机名
pHost = gethostbyname(name);//获得主机结构
这就需要给每台服务器分配ip地址,互联网上的网站无穷多,我们不可能记住每个网站的ip地址,这就产生了方便记忆的域名管理系统dns,他可以把我们输入的好记的域名转换为要访问的服务器的ip地址. 也就是为了方便我们浏览互联网上的网站而不用去刻意记住每个主机的ip地址,dns服务器就应运而生,提供将域名解析为ip的服务,从而使我们上网的时候能够用简短而好记的域名来访问互联网上的静态ip的主机。例如:对于ip地址为210.73.140.5的主机来说,其主机标识为00000101,对于ip地址为210.73.140.16的主机来说它的主机标识为00010000mfc socket onclose,以上两个主机标识的前面三位全是000,说明这两个ip地址在同一个网络区域中,这两台主机在交换信息时不需要通过路由器进行10.73.60.1的主机标识为00000001,210.73.60.252的主机标识为11111100,这两个主机标识的前面三位000与011不同,说明二者在不同的网络区域,要交换信息需要通过路由器。没有显示的话要手动连接,先在控制台中找到那个建立游戏主机的ip地址(一般主机建立游戏前就要先记住这个ip,没记住的话也没事,在游戏中还可以呼出控制台进行查看),一般局域网都是192.168....开头的,所以看一下控制台里前些行的信息就能找到主机的局域网ip地址,然后在要加入者控制台输入框中输入“connect”(小写)后面跟主机的ip地址,然后按下回车键就可以加入主机已经建好的游戏了,最多可以4人,也可以破解人数限制进行更游戏。
showmsg_edit->SetWindowText("绑定IP地址:" + IP);
AfxBeginThread(&server_thd,0); //开启新线程处理
}
//发送按钮响应事件
void CsFileDlg::OnBnClickedBtnsend()
{
// TODO: 在此添加控件通知处理程序代码
CString s;
char * msg;
send_edit->GetWindowText(s);
msg = (char*)s.GetBuffer(s.GetLength()); //获取发送的数据的缓冲区的指针
if(s == "")
{
MessageBox("请输入信息");
}
else if(send(sock, msg, strlen(msg), 0) == SOCKET_ERROR) //发送数据,并判断是否成功
{
update("发送失败\r\n");
}
else
{
update("我:" + s + "\r\n");//消息上屏
send_edit->SetWindowText("");//清空输入

send_edit->SetFocus();//并重获焦点
}
}
//添加线程函数server_thd():
UINT server_thd(LPVOID p)
{
WSADATA wsaData;
WORD wVersion;
wVersion = MAKEWORD(2,2);
WSAStartup(wVersion,&wsaData);
SOCKADDR_IN local_addr;
SOCKADDR_IN client_addr;
int iaddrSize = sizeof(SOCKADDR_IN);
int res;
char msg[1024];
CString port;
CsFileDlg * dlg = (CsFileDlg *)AfxGetApp()->GetMainWnd(); //得到应用程序活动主窗口的指针
dlg->port_edit->GetWindowText(port);//获得端口地址
if(port=="")
{
AfxMessageBox("请输入端口号");
return 0;
}
//为local_addr赋值,创建soket
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(atoi(port)); //atoi, 把字符串转换成整型数
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//创建listen_sock
if( (listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET )
{
dlg->update("创建失败\r\n");
return 0;
}
//绑定
if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)))。 if( bind(client_socket,(struct sockaddr*)&client_addr,sizeof(client_addr)))。 if (bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)。
{
dlg->update("绑定错误,换一个端口试试吧~\r\n");
return 0;
}
listen(listen_sock, 1); //开始,允许最大数为1
dlg->star_btn->EnableWindow(FALSE); //开启服务器按钮灰化

当程序开始运行时,系统发送(sendmessage)wm_ncpaint消息,此时程序的窗口边框应该被显示,但是此时我们没有作任何显示的操作,而是将窗口隐藏,showwindow(sw_hide)将把窗口的ws_visible属性去掉,继续执行,程序将检查ws_visible属性,如果没有则显示窗口,所以又发送了一个wm_ncpaint消息。你可以在绑定模式下添加非绑定列,在你希望显示一个按钮列或者链接列让用户操作一些特定行时这显得很有用,另外也可以用非绑定列显示一些由绑定列计算而得到的值。介绍了一下五个小技巧: 1.让list control有check box 2.让list box有check box 3.spin control与edit control的绑定 4.可以设置背景和文字颜色的static控件 5.在static控件中显示bmp。
dlg->update("已成功开启....\r\n");
//接受连接请求
if(bind(sock,(sockaddr *)&addr_in,sizeof(sockaddr))==socket_error)。if(connect(sock, (sockaddr*)&saproxy, sizeof(sockaddr)))。 if (bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)。
{
dlg->update("接受连接请求失败\r\n");
return 0;
}
else
{
CString port;
port.Format("%d", int(ntohs(client_addr.sin_port)));
dlg->update( "已连接来自:" + CString(inet_ntoa(client_addr.sin_addr)) + " 端口:" +
port+"\r\n");
}
////////////接收数据
while(1)
{
recv和send函数如果成功都会返回接收或者发送的数据字节数,否则返回-1。判断text类型数据是否为空 判断text类型数据是否为空 text的字段是不是空的,用了text="" 这样去判断会报错误提示(不能比较或排序 text、ntext 和 image 数据类型,除非使用 is null 或 like 运算符), 解决办法是用datalength(字段名)=0去判断是否为空,如果数据内容长度是0个字符,那就是空了。recv.log是onvif接收到的soap数据,没接收一条,都会在recv.log中记录。
{
dlg->update("失去连接\r\n");
dlg->star_btn->EnableWindow(TRUE);
break;
}
else
{
dlg->update("客户端:" + (CString(msg)).Mid(0,res)+"\r\n");
}
}
return 0;
}
客户端代码:
// cFileDlg.cpp : 实现文件
//
#include <winsock2.h>
#include "stdafx.h"
#include "cFile.h"
#include "cFileDlg.h"
#include "afxdialogex.h"
#pragma comment(lib, "WS2_32.lib")
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
SOCKET sock; //创建全局的soket
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-106289-1.html
爱千玺
日本海军普遍吨位3300吨以上