惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
博客园 - Franky
GbyAI
GbyAI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
爱范儿
爱范儿
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
博客园_首页
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recent Announcements
Recent Announcements
Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
C
CERT Recently Published Vulnerability Notes
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
L
LangChain Blog
L
LINUX DO - 最新话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Hacker News: Front Page
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
AI
AI
T
Troy Hunt's Blog
Microsoft Azure Blog
Microsoft Azure Blog
阮一峰的网络日志
阮一峰的网络日志
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
罗磊的独立博客
S
Secure Thoughts
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
人人都是产品经理
人人都是产品经理
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
E
Exploit-DB.com RSS Feed
Attack and Defense Labs
Attack and Defense Labs

博客园 - 饽饽

C语言指针的用法 CRC 循环冗余校验码 (VC编程) 无线网卡或笔记本找不到网络的一个原因 (one reason of your laptop cannot find wireless network) 电脑能够上QQ,可以ping IP,玩网络游戏,就是不能上网,收发电子邮件的解决办法 有关学校的打油诗 CMPP2.0 协议SP端的·NET开发 C++中的虚函数(virtual function) - 饽饽 - 博客园 MIMO的文章 VC++调用其它语言编写的程序 - 饽饽 - 博客园 VC++调用其它程序2 - 饽饽 - 博客园 Vc编程基础 VC MFC基本控件的使用 VC基础教程 VISCAL C++下WINSOCK CONTROL类(ACTIVEX)的使用 用Winsock实现语音全双工通信使用 socket编程原理 VC常用技巧集锦 windows网络编程 用Winsock控件实现点对点通信
基于WINSOCK控件的VC网络通讯程序
饽饽 · 2005-05-16 · via 博客园 - 饽饽

基于WINSOCK控件的VC网络通讯程序

马进  林永君 马永光 吕丽霞

华北电力大学仿真控制技术实验室,河北保定

作者简介: 马进(1971- ),男,籍贯 河北任丘,华北电力大学仿真控制技术研究所工程师,工学硕士,现从事电厂负荷优化、仿真机的开发与研究工作。

该程序为原国家电力公司青年促进费项目“发电厂厂级负荷优化调度”中的一部分。项目编号:SP11-2001-05-66

摘要:介绍在VISCAL C++ 6.0 环境下,使用Winsock控件进行网络通讯的一种方法。Winsock控件的使用简单,可以方便地应用在使用VC++进行编程的网络通讯程序中。

关键字:Winsock控件  局域网  VC6.0

中图分类号:           文献标识码:          文章编号:

引言:

    随着计算机技术的发展和网络的不断普及,网络通讯程序的应用越来越普遍,各种软件开发平台也为网络通讯程序的开发提供了不同形式的类和控件。在利用Visual C++ 进行开发时,可以使用Csocket类;在利用Visucal Basic 进行开发时,可以使用Winsock 控件。有关Csocket类在VC中的使用和Winsock 控件在VB中使用,已经有许多文章、资料进行的介绍,这里不再赘述。同时也应注意到,利用VC的CSocket类需要对网络通讯的机制和参数有较深的了解,需要较深的计算机知识。虽然CSocket对Winsock进行了封装,但是它的函数调用仍然比较复杂,使用起来不容易。与此相反,在利用VB编程时,各种控件的使用比较简单,不需要许多的参数。利用VB中的Winsock 控件进行开发比较容易,但VB本身的功能不如VC强大,在进行开发时有时会受到一定程度的限制。在VC中利用Winsock控件的使用难度则介于上述二者之间,只需对少许一些参数做简单设置即可。如果在用VC编制程序时需要进行网络通讯而又不想花费过多的时间,在VC程序中插入Winsock控件是一种合适的方法。利用Winsock控件可以编制一个简单的通讯程序,用于局域网之间的微机通讯。

1 Winsock控件的使用方法

1.1通讯协议的选择

Winsock控件提供了访问 TCP 和 UDP 网络服务的方便途径。采用TCP协议可以提供双向的、可靠的、有序的和无重复投递的数据流。TCP允许创建和维护与远程计算机的连接,连接两台计算机就可彼此进行数据传输。用户数据文报协议 (UDP) 是一个无连接协议。采用UDP协议,支持双向的数据流,但不保证有序、可靠或无重复的投递。但计算机并不建立连接。

在使用中,采用TCP协议的编程模型应用最为广泛,因为面向连接协议提供了一系列的数据纠错功能,可以保证在网络上传输的数据及时、无误地到达对方,Internet上的多数服务(WWW、FTP、Telnet、SMTP)就是靠此协议运转的。采用UDP协议由于不用建立连接,传输比连接协议快,无数据纠错功能,不保证数据的可靠传递。在这里本文只介绍使用TCP/IP协议进行编程的方法。

1.2使用方法和主要函数

    Winsock控件的使用方法和步骤如下图所示。

1.2.1 VARIANT类型变量的使用

   Winsock控件使用的一个特殊的数据类型为VARIANT结构,其中vt的值类型说明了它所存储的数据,vt的几个主要的值类型及值域为:

  类型                      值域                说明

vt=VT_BSTR          bstrVal         字符串类型

vt=VT_I2                  Ival                     整数类型

vt=VT_ERROR      scode                  错误代码

在使用之前,应对VARIANT变量的类型和值域进行赋值。一般的使用方法为:

VARIANT [variant name]

[variant name].vt=[variant type]

[variant name].[variant type]=[value]

例如:

   Cstring  m_host;

   m_host="Room312";

   VARIANT  vtHost;

   vtHost.vt=VT_BSTR;

   vtHost.bstrVal=m_host.AllocSysString();

1.      2.2 Server程序使用的主要函数

    Bind()函数指定用于 TCP 连接的 LocalPort 和 LocalIP。

    Listen()函数设置侦听模式。该方法仅适用于 TCP 连接。

    Accept()在处理 ConnectionRequest 事件时用这个方法接受新连接。

    SendData()用于数据的发送。

    Close()关闭与对方的连接。

1.2.3Client程序使用的主要函数

    Connect()要求连接到远程计算机。

    GetData()得到远程计算机上的数据。

2 使用Winsock控件的局域网通讯程序

2.1 Server程序

   利用ClassWizard建立一个ServerDemo程序,注意选择SDI,支持ActiveX,将View类设为CFormView类, 从Project->Add File->Compont and Control, 在对话框中选Registered ActiveX,选择Microsoft WinSock Control ,点击Insert按钮,依照缺省设置即可。这样在工程文件中会出现mswinsockcontrol类编辑ServerDemo程序的主对话框,可以看到在控件面版上出现mswinsockcontrol类的控件。在对话框中加入控件和相应的变量,如表1所示

控件

控件ID

变量名

类型

Edit

IDC_EDIT1

 m_edit

CString

按钮

IDC_SEND

Winsock

IDC_WINSOCK1

 m_server

控制

Winsock

IDC_WINSOCK2

 m_connect

控制

(1)在ServerDemoView.h中,加入以下变量

 VARIANT localport;

 VARIANT localip;

 CString strport;

 CString strip;

 VARIANT vtCommand;

 CString m_command;

 VARIANT vtData;

 VARIANT vtType;

 VARIANT vtMaxlen;

(2)在ServerDemoView .cpp的构造函数中加入:

    localport.vt=VT_BSTR;

    localip.vt=VT_BSTR;

    strport="4000";

   strip="128.1.0.139";//在程序中应将“128.1.25.240”设为自己server  

                      //的IP地址

   vtCommand.vt=VT_BSTR;

   m_command="Server Send";

   vtData.vt=VT_BSTR;

   vtType.vt=VT_ERROR; 

(3)利用ClassWizar映射OnInitialUpdate()的响应:在其中加入代码:

   localport.bstrVal=strport.AllocSysString();

   localip.bstrVal=strip.AllocSysString();

   m_server.Bind(localport, localip);

   m_server.Listen();

(4)利用ClassWizar响应IDC_WINSOCK1的ConnectionRequest事件,在OnConnectionRequestWinsock1()中加入代码:

    if(m_connect.GetState()==0 )

       m_connect.Accept(requestID);

    else

    AfxMessageBox("no more connects",MB_OK);

(5)利用ClassWizar映射ID_SEND的动作:OnSend(),在其中加入代码:

    m_edit.GetWindowText(m_command);

    vtCommand.bstrVal=m_command.AllocSysString();

    m_connect.SendData(vtCommand);

(6)利用ClassWizar响应ID_WINSOCK2的DataArrival事件,在OnDataArrivalWinsock2()中加入代码:

    CString m_MBody;

    vtMaxlen.vt=VT_I2;

    vtMaxlen.iVal=bytesTotal;

    vtData.bstrVal=strport.AllocSysString();

    vtType.bstrVal=strport.AllocSysString();

    m_connect.GetData(&vtData,vtType,vtMaxlen);

    m_MBody=vtData.bstrVal;

    m_edit.SetWindowText( m_MBody);

(7)利用ClassWizar响应ID_WINSOCK2的Close()事件,在OnCloseWinsock2()中加入代码:

    m_connect.Close();

(8)在DestroyWindow() 中加入:

    m_server.Close();

    m_connect.Close();

22 Client程序

    利用ClassWizard建立一个ClientDemo程序,注意选择SDI,支持ActiveX,将View类设为CFormView类, 从Project->Add File->Compont and Control, 在对话框中选Registered ActiveX,选择Microsoft WinSock Control ,点击Insert按钮,依照缺省设置即可。这样在工程文件中会出现mswinsockcontrol类。编辑ClientDemo程序的主对话框,可以看到在控件面版上出现mswinsockcontrol类的控件。在对话框中加入控件和相应的变量,如表2所示

表2控件表

控件

控件ID

变量名

类型

Edit

IDC_EDIT1

 m_edit

CString

按钮

IDC_CONNECT

 m_connect

控制

按钮

IDC_SEND

Winsock

IDC_WINSOCK1

 m_socket

控制

(1)在ClientDemoView.h中,加入以下变量

   CString m_host;

   CString m_port;

   VARIANT vtHost;

   VARIANT vtPort;

   VARIANT vtData;

   VARIANT vtType;

   VARIANT vtMaxlen;

   VARIANT vtCommand;

   CString m_command; 

(2)在ClientDemo.cpp的构造函数中加入:

   m_host=_T("Room312");//在程序中将“Room312”设为自己server的主机

                        //名

   m_port=_T("4000");   //端口设为4000;

   m_command=_T("Client send");

   vtHost.vt=VT_BSTR;

   vtPort.vt=VT_BSTR;

   vtData.vt=VT_BSTR;

   vtType.vt=VT_ERROR;

   vtCommand.vt=VT_BSTR;

(3)利用ClassWizar映射ID_CONNECT的动作:在OnConnect()中加入代码:

   m_socket.SetRemoteHost("Room312");//在程序中将“Room312”设为自己

                                  //server的主机名

   m_socket.SetRemotePort(4000);

   vtHost.bstrVal=m_host.AllocSysString();//见CString类字符串转化为

 //系统字符串

   vtPort.bstrVal=m_port.AllocSysString();

   m_socket.Connect(vtHost,vtPort);

   if(m_socket.GetState()==0) //如果m_socket已经断开连接,将connect

                            //设置为可用

       m_connect.EnableWindow(true);

   else

      m_connect.EnableWindow(false);

(4)利用ClassWizar映射ID_SEND的动作:在OnSend:

    m_edit.GetWindowText(m_command);

    vtCommand.bstrVal=m_command.AllocSysString();

    m_socket.SendData(vtCommand);

(5)利用ClassWizar响应ID_WINSOCK1的DataArrival事件,在 OnDataArrivalWinsock1(long bytesTotal)中加入代码:

   CString m_MBody;

   vtMaxlen.vt=VT_I2;

   vtMaxlen.iVal=bytesTotal;

   vtData.bstrVal=m_host.AllocSysString();

   vtType.bstrVal=m_port.AllocSysString();

   m_socket.GetData(&vtData,vtType,vtMaxlen);

   m_MBody=vtData.bstrVal;

   m_edit.SetWindowText(m_MBody);

(6)在DestroyWindow()中加入:

    m_socket.Close();

(7)利用ClassWizar响应ID_WINSOCK1的Close事件,在OnCloseWinsock1()中加入代码:

    m_socket.Close();

    if(m_socket.GetState()==0)

      m_connect.EnableWindow(true);

else

      m_connect.EnableWindow(false);

3.程序演示及结论

将上述程序分别编辑、连接为执行程序,生成serverdemo.exe和clientdemo.exe文件。确认程序中主机名和IP地址无误。如果计算机没有连网,可以在程序中使用本机的主机名和IP地址。首先运行serverdemo.exe。它自动进入到监听状态。随后运行clientdemo.exe,点击connect按钮。如果client与server 连接成功,connect按钮变为灰色(不可用)。连接成功后,在编辑框中输入文字,点击send按钮,在serverdemo程序的编辑框中可以看到clientdemo程序发送的文字。同样,在serverdemo的编辑框中输入文字,点击send按钮,在clientdemo程序的编辑框中可以看到serverdemo程序发送的文字。

通过上述程序可以看到,同MFC的Csocket类相比,Winsock控件的使用简单方便。程序中并未涉及Winsock最基本的API函数以及TCP/IP的相关知识,编程简单明了,是在VC++程序中进行网络通讯的一种简便方法。

参考文献:

      1、Visual C++(第四版) 原著David J. Kruglinshi  潘爱民 王国印译   机械工业出版社   1999.1

      2、Visual C++ 6开发使用指南 (美)Kate Gregory 著 前导工作室译  机械工业出版社  1999

A Kind of LAN Communication Program Based on Winsock Control

Under VC++6.0 Environment

ABSTRACTT: A method for network communication with Winsock control is present under VC++6.0 environment. By inserting Winsock control in program and using its functions, the program can communicate with other programs. Most low functions of CSocket class are packed in Winsock control, it is easy to use Winsock control in network communication program. 

Key Words: Winsock Control  LAN  VC++

马进(1971-),男,硕士,工程师,从事火电厂优化调度、锅炉仿真模型的研究。

单位:华北电力大学仿真控制技术实验室

通讯地址:河北保定市华北电力大学93#信箱

邮编:071003

EMAIL:MAJINWJ@SINA.COM;MAJIN@NCEPU.EDU.CN

电话:0312-7522048, 13831218862