急求一个用mfc编写的监控管理系统的客户端和cs1.6服务器客户端端…

mfc做客户端,与linux下的服务器进行通信,求客户端实例及相关知识_mfc吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:12,189贴子:
mfc做客户端,与linux下的服务器进行通信,求客户端实例及相关知识收藏
利用MFC做一个简单的客户端,求与题相关的知识。
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或一个简单的C客户端/服务器的CORBA_客户端脚本_网页开发_或代码
| 文章 >> 网页开发 >> 客户端脚本
一个简单的C客户端/服务器的CORBA
{A6}{A7}{A8}{A9}{A10}{A11}{A12}{A13}{A14}{A15}{A16}{A17}{A18} - ;简介 {A19}是一个不以营利为目的的组织,旨在促进面向对象技术的使用。除其他事项外,它定义了UML和CORBA标准。 CORBA是一种常见的ORB体系结构的缩写。短语常见的体系结构是指一个技术标准,所以CORBA仅仅是一个所谓的ORB技术标准。反过来,ORB是对象请求代理,这是一个称为远程过程调用(RPC)的旧技术的面向对象版本的缩写。一个ORB或RPC是在不同的("远程??的过程,可能在同一运行机制上一个对象(或调用过程)调用操作,或不同的,电脑的编程水平,这些"事实上,CORBA使人们有可能在一种编程语言,例如Java中,写的客户端应用程序在不同的编程语言实现服务器远程调用远程??电话类似于"在本地??电话。说,C,出现这种语言的独立性,因为服务器应用程序的公共接口定义在IDL文件和CORBA IDL到很多编程语言,包括C语言,C,JAVA,COBOL,阿达,Smalltalk和Python的定义映射。{A20} - ;接口定义语言(IDL) IDL文件中定义的公共应用程序接口(API),它是由服务器应用程序中的对象暴露。 CORBA对象的类型被称为一个接口,这是在概念上类似于一个C类或一个Java接口。下面是一个例子IDL文件。module Finance {
typedef sequence&string& StringS
struct AccountDetails {
exception insufficientFunds { };
interface Account {
void deposit(in double amount);
void withdraw(in double amount) raises(insufficientFunds);
readonly attribute AccountD
};正如上面的例子表明,IDL类型可分为模块。这种构造提供一个类似的C命名空间或Java包的目的:它的地方类型的名称前缀,以防止命名空间污染。在IDL作用域运算符是什么??代码>::???例如,财政部:帐户是在财务模块中定义帐户类型全范围的名称。 IDL接口可能包含操作和属性(和,如果你愿意,也嵌套类型)。许多人误以为,属性是类似的概念在C的实例变量(在Java领域)。这是不对的。属性是简单的GET - NBSP对语法糖和定式操作。属性可以是只读的,在这种情况下,它映射到只是得到式操作。操作的参数指定的方向,可以在(该参数是从客户端向服务器传递的意义),输出(参数是通过从服务器返回给客户端)或INOUT(参数是通过在两个方向上)。操作也可以有返回值。一个操作可以提高(抛出)异常,如果出现错误。有超过30个预定义的异常类型,系统异常,所有的操作可以抛出,虽然在实践中系统异常CORBA运行系统提出更加频繁比由应用程序代码。除了预先定义的系统异常,新异常类型可以定义一个IDL文件。这些被称为用户定义的异常。一个提高操作的签名条指定用户定义的异常,它可能会引发。参数的操作(和返回值),可内置的类型,例如,字符串,布尔值或长或用户定义的??"类型,在IDL文件中宣布的。用户定义的类型可以下列任何一种:一个结构。这是一个C / C结构或一个Java类,只包含公共领域。一个序列。这是一个集合类型。它像一个一维数组,可以增大或缩小。的IDL - to - C映射早在C标准模板库的话,不幸的是,没有一个IDL序列映射到一个std::vector的。相反,IDL到C的映射定义自己的矢量数据类型。一个数组。在IDL文件中指定一个IDL阵列的尺寸,所以数组是固定大小的,也就是说,它不能增长或收缩在运行时的。在IDL阵列很少使用。序列类型更加灵活,所以是比较常用的。一个typedef。这定义了一个新名称为现有类型。例如,下面的语句定义,作为短期的年龄:{C}一个共同的,而且很重要的,使用的typedef是联想到一个序列或数组声明的名称。例如: typedef sequence&string& StringS 工会。这种类型在运行时可容纳几个值之一,例如: union Foo switch(short) {
case 1: boolean
case 2: long
case 3: string
Foo的实例可以容纳一个布尔值,长期或一个字符串。 case标签的值是当前活动的。枚举是概念上类似于一个整数常量声明集合。例如: enum color {red, green, blue}; 内部,CORBA使用整数值,代表不同的枚举值。{A21}的IDL映射到编程语言正如已经提到的,IDL是用于定义是由服务器应用程序中的对象暴露的公共API。 IDL定义的方式,是独立于任何特定的编程语言这个API。然而,对CORBA是有用的,必须是从IDL映射到一个特定的编程语言。例如,IDL到C的映射,使人们能够开发CORBA应用程序在C,而IDL到Java映射,使人们能够Java开发CORBA应用程序。 CORBA标准目前定义了从IDL的映射以下编程语言:C语言,C,JAVA,阿达,Smalltalk的,COBOL,PL / I的LISP,Python和IDLScript。这些官方认可的语言映射在不同的CORBA产品提供源代码的应用程序的可移植性。有其他一些语言,如埃菲尔铁塔,TCL和Perl的非官方映射。{A22} IDL编译器一个IDL编译器转换成IDL定义(例如,结构,工会,序列等)到类似的定义在一种编程语言,如了C,Java,Ada或COBOL。此外,每个IDL接口,IDL编译器生成两个存根代码也被称为代理类型和骨架代码。这些条款往往造成混乱,所以我以下解释:一个存根字典中的定义是"更大的东西后剩下的短端已经用完,例如,一支铅笔存根或一根烟存根??在传统的(非分布式)编程,过程是一个虚拟执行一个程序,是用来防止"未定义标签链接时错误??。像CORBA的分布式中间件系统,实施后的存根程序/对象的本地电话客户端远程调用。存根使用一个进程间通信机制(如TCP / IP套接字)发送请求到服务器的过程和收到答复。长期代理是经常被用来代替存根。一个代理字典的定义是"授权行事另一个的人??一个CORBA代理只是一个客户端对象,它代表的一个服务器进程中的"真实的吗??对象的行为。当客户端应用程序调用一个代理操作,代理使用进程间通信机制,传送到一个​​服务器进程中的"真正的对象的请求;??然后等待代理收到答复,并传回这个答复在客户端应用程序级的代码。长期代码阅读传入请求,并派遣他们到应用层的对象是指服务器端代码。长期骨架可能看起来像一个奇怪的选择。然而,使用字骨架不仅限于讨论有关骨骼,更普遍,它指的是"基础配套设施吗??就是所谓的,因为它提供配套基础设施,需要实现服务器应用程序的框架代码。一个CORBA产品必须提供IDL编译器,但CORBA规范不状态的编译器或命令行选项,它接受的名称是什么。这些细节变化从一个CORBA产品到另一个。{A23}进行远程调用 CORBA使用长期的仆人,是指用一种编程语言(如C或Java),实现IDL接口编写的一个对象。下图显示了一个客户端应用程序调用一个对象/服务器过程中的仆人的操作时会发生什么。{S0}在客户端的应用程序代码后,本地代理对象(记得,是由IDL编译器生成的代理类)的调用。代理乘警请求被调用的操作名称等信息,以及其和inout参数成二进制缓冲区。代理对象,然后通过这个二进制缓冲区ORB库(提供与CORBA产品),它通过网络传输的请求消息到服务器进程。 ORB在客户端进程等待读取服务器进程答复消息。 ORB的答复缓冲区返回的代理对象,解组inout和输出参数和返回值(或异常),并返回这些客户端应用程序代码。在服务器端,ORB线程里面坐落在一个事件循环,等待传入的请求。当一个请求到达时,ORB读取请求的二进制缓冲区,并传递一些代码,解组的参数和调度的目标仆人要求。解组和调度执行的代码是遍布两部分组成。其中一个组件是一个POA,稍后我将在本文中讨论。另一部分是骨架,是由IDL编译器生成的代码。生成的框架代码没有明确显示在图中,因为它需要的是servant类继承基类的形式。当仆人返回操作,骨架代码乘警成二进制缓冲区inout和输出参数(或异常),这是通过服务器端ORB的POA,在网络上传输的应答消息返回客户端进程。{A24} CORBA服务许多编程语言都配备了一个标准化的功能库和/或补充的核心语言的类。这些标准化的图书馆通常提供集合数据类型(例如,链表,套,哈希表等),文件输入输出等功能,为各种广泛的应用发展是有用的。如果你问一个开发商说,JAVA,C或C写一个应用程序,但不使用这种语言的标准库,那么开发商将很难。存在类似情况的CORBA。 CORBA的核心部分(一个面向对象的RPC机制的建立与IDL和上线协议,共同的)本身是有限的使用的,以同样的方式,剥去其标准化的图书馆一种编程语言的使用有限。大大增强了对CORBA的力量是一个标准化的服务称为CORBA的收集服务,提供各种各样的分布式应用程序的发展功能非常有用。 CORBA服务的API,在IDL定义。实际上,你能想到的CORBA服务,像一个标准化的类库。然而,有一点要注意的是,大多数CORBA服务作为预建的服务器应用程序,而不是到自己的应用程序链接库提供的。正因为如此,CORBA服务真的是一个分布式,标准化的类库。一些常用的CORBA服务包括以下内容:命名服务和交易服务,让服务器应用程序的宣传对象,从而使客户端应用程序,很容易找到对象。大多数CORBA应用程序使用同步,一到一个通讯。然而,有些应用需要,许多到很多,异步通信,或有什么很多人所说发布和订阅通信。各种CORBA服务被定义为支持这种类型的通信。在分布式系统中,它有时需要跨越多个数据库,使一个事务被提交时,它是保证所有数据库更新或更新任何交易。对象事务服务(OTS)提供了这个功能。{A25}开发一个简单的客户 - 服务器应用程序我已经使用了{A26}眼镜蛇实施开发一个示例客户端 - 服务器应用程序。 Orbacus可用于Java和C。{A27}业务逻辑域我的示范服务器应用程序提供加密()和解密()操作。客户端应用程序在服务器中的对象调用加密()来加密一些纯文本。后来客户端调用解密()来解密文本。 {A28}这是一个最简单的加密技术加密/解密算法是基于。它是一种替代密码,在纯文本中每个字母替换下来的字母表中的位置是固定数量的信。我添加了一个加密密钥的XOR运算后移位操作的模糊关系。你可以看到如下图的替代技术:{A29}编写的IDL在执行客户端 - 服务器应用程序的第一步是写一个IDL文件定义服务器的公共API。这包括一个接口,可提供加密()和解密()操作。界面还包含一个关闭()操作,这样我们就可以正常要求服务器终止。 IDL的示范应用程序如下:
interface CaesarAlgorithm {
typedef sequence&char&
charsequence encrypt(in string info,in unsigned long k,in unsigned long shift);
string decrypt(in charsequence info,in unsigned long k,in unsigned long shift);
boolean shutdown();
};{A30}生成的骨架和存根编写的IDL文件后,我们转换成相应的C定义运行Orbacus提供的IDL编译器的IDL定义。idl crypt.idl运行该命令会生成以下文件:crypt.h和crypt.cpp:这些文件的制定和实施在IDL文件中定义的IDL类型(如结构,工会,序列等)对应的C类型。这些文件还实施了相应的IDL接口的客户端代理类。crypt_skel.h和crypt_skel.cpp:这些文件的制定和实施服务器端的功能,需要读取传入的请求,并派遣公务员(代表CORBA对象的C对象)。注意,CORBA规范不规范的名称IDL编译器,和不同的CORBA实现可能会使用不同的名称。例如,在Orbacus IDL编译器,Orbix的和omniORB被称为IDL,而陶调用它的IDL编译器tao_idl,以及双方的VisiBroker和轨道叫他们idl2cpp。{A31}实现servant类下一步是落实仆人类,即一个C类实现IDL接口。要做到这一点,我们创建一个类(CryptographicImpl)(POA_CaesarAlgorithm)由IDL编译器生成的骨架类继承。你可以看到在下面。#include &iostream&
#include &string&
#include &OB/CORBA.h&
#include &crypt_skel.h&
class CryptographicImpl : virtual public ::POA_CaesarAlgorithm,
virtual public PortableServer::RefCountServantBase
CORBA::ORB_
CryptographicImpl(CORBA::ORB_var orb)
this-&orb =
virtual ::CaesarAlgorithm::charsequence*
encrypt(const char* info,::CORBA::ULong k,::CORBA::ULong shift)
throw(::CORBA::SystemException)
std::string msg =
int len = msg.length();
::CaesarAlgorithm::charsequence* outseq =
new ::CaesarAlgorithm::
outseq-&length(len + 1);
std::string::iterator i = msg.begin();
std::string::iterator end = msg.end();
int j = 0;
while (i != end)
(*outseq)[j++] = *i++;
(*outseq)[len] = '\0';
virtual char* decrypt(const ::CaesarAlgorithm::charsequence&
info,::CORBA::ULong k,::CORBA::ULong shift)
throw(::CORBA::SystemException)
char* r = CORBA::string_alloc(info.length());
for (int i = 0;i & info.length() - 1;i++)
= info[i];
r[info.length() - 1] = '\0';
virtual ::CORBA::Boolean shutdown() throw(::CORBA::SystemException)
orb-&shutdown(false);
return true;
};仆人实现IDL接口定义的操作。当客户端远程调用,调度的代码(在继承POA_CaesarAlgorithm类中实现)解组参数传入的请求,并调用运行。{A32}创建服务器实施的仆人类,我们现在必须执行的服务器主线。执行一些CORBA的初始化步骤,创建的仆人,宣传其命名服务对象引用,然后进入一个事件循环等待传入的请求。显示的代码之前,有两个CORBA概念,我需要解释:POA和POA管理器。阅读这篇文章到目前为止,你可能有印象,客户端调用远程对象上的操作,和那些生活在一个服务器进程的远程对象。这几乎是正确的的。在现实中,在容器中的对象的生活称为一个POA(一词可移植对象适配器,但这个名字的由来是不是特别有趣),以及POA的,反过来,住在一个服务器进程。这样做的动机是不同的POA可以提供不同的服务质量(或CORBA中的术语政策)。例如,一个POA可能是单线程的,而另一个POA可能是多线程。一个POA提供的服务质量,是适用于在该POA的仆人。因此,在一个行动纲领"和其他公务员在另一个POA的通过将一些公务员,一个服务器进程可以承载与各种不同的服务质量对象:有些对象可能是单线程的,有的则是多线程,有些对象可能瞬态(意义临时),而其他对象可能是持久的(意思是,客户端应用程序可以继续与服务器进程崩溃,即使是重新启动的对象通信)。 CORBA提供了一个API,使服务器开发人员能够创建多个POA的,每一个潜在的不同质量的服务。 CORBA运行在服务器系统预先创建一个"rootPOA??多线程和瞬态。因为,服务质量是适合我们的演示服务器的需求,我们并不需要显式地创建一个POA。一个水龙头(或龙头美国人称之为)是用于开启和关闭的水流量。 POA管理器类似一个水龙头,除了它控制传入的请求流。 CORBA服务器启动时,与根POA关联的POA管理器是一个保持状态,这意味着如果任何来自客户端的的请求到达,那么他们将排队。这种状态使一个服务器进程来完成它的初始化,而不必担心处理传入的请求。当服务器完成其初始化,它把进入活跃状态的POA管理器(S),使传入的请求,可以派遣,通过POA的,公务员。初始化ORB。获取根POA。后来,我们将这个POA创建一个servant对象和激活(即插入)。访问根POA的POA管理器。最初,这个POA管理器是在保持状态,因此任何传入请求排队。当服务器的初始化完成后,我们会把这个POA管理器进入活跃状态,使传入的请求,可以派出。获取命名服务的参考后,使我们创建了一个仆人,我们可以出口其命名服务对象引用。动态创建一个CryptographicImpl仆人对象。调用servant_to_reference()为我们提供了一个仆人的对象引用。参考转换为一个字符串,以显示它。重新绑定()操作是用来注册命名服务的仆人的对象引用。在ORB进入一个事件循环,所以它可以等待传入的请求。公务员是引用计数。当创建一个仆人,它的引用计数初始化 1。现在我们的仆人完成后,我们减少它的引用计数,因此CORBA运行系统知道它可以安全地删除。销毁的ORB。{A33}实现客户端客户端应用程序执行一些CORBA的初始化步骤,从命名服务检索服务器的对象引用,然后进入一个循环,它调用加密()和解密()。当客户端完成的,它调用关闭()要求服务器终止。#include &iostream&
#include &string&
#include &OB/CORBA.h&
#include &OB/Cosnaming.h&
#include &crypt.h&
using namespace
int main(int argc, char** argv)
CORBA::ORB_
orb = CORBA::ORB_init(argc, argv);
CORBA::Object_var rootContextObj =
orb-&resolve_initial_references(&NameService&);
CosNaming::NamingContext_var nc =
CosNaming::NamingContext::_narrow(rootContextObj.in());
CosNaming::N
name.length(1);
name[0].id = (const char *) &CryptographicService&;
name[0].kind = (const char *) &&;
CORBA::Object_var managerObj = nc-&resolve(name);
::CaesarAlgorithm_var manager =
::CaesarAlgorithm::_narrow(managerObj.in());
string info_in,exit,
CORBA::String_var info_
::CaesarAlgorithm::charsequence_
unsigned long key,
cout && &\nCryptographic service client& &&
cout && &----------------------------& &&
if (cin.fail())
cin.clear();
cout && &Enter encryption key: &;
} while (cin.fail());
if (cin.fail())
cin.clear();
cout && &Enter a shift: &;
} while (cin.fail());
getline(cin,dummy);
cout && &Enter a plain text to encrypt: &;
getline(cin,info_in);
inseq = manager-&encrypt
(info_in.c_str(),key,shift);
cout && &------------------------------------------&
cout && &Encrypted text is: &
&& inseq-&get_buffer() &&
info_out = manager-&decrypt(inseq.in(),key,shift);
cout && &Decrypted text is: &
&& info_out.in() &&
cout && &-------------------------------------------&
cout && &Exit? (y/n): &;
} while (exit!=&y&);
manager-&shutdown();
} catch(const std::exception& std_e){
cerr && std_e.what() &&
}catch(const CORBA::Exception& e) {
cerr && e &&
if (!CORBA::is_nil(orb)){
orb-&destroy();
cout && &Ending CORBA...& &&
} catch(const CORBA::Exception& e)
cout && &orb-&destroy failed:& && e &&
}初始化ORB。获取命名服务的参考。命名服务呼叫解决()(这意味着查找)检索服务器的对象引用。窄()操作,在本质上是一个类型转换。我们已经缩小()从命名服务对象引用接收到正确的亚型,所以我们可以调用它的操作。制作加密()操作的远程调用。制作解密()操作的远程调用。请关机()操作的远程调用。{A34}运行客户端 - 服务器应用程序一旦我们已经实现了客户端和服务器,它的时间将它们连接。因为我们的演示客户端和服务器交换通过命名服务对象引用,我们必须确保,命名服务(即所谓Orbacus nameserv)正在运行。我们使用一些命令行选项告诉命名服务的主机和端口,它应该听。nameserv -OAhost localhost -OAport 8140在此之后,我们就可以开始与命令行选项告诉它如何联系的命名服务的服务器。server -ORBInitRef NameService=corbaloc:iiop:localhost:8140/NameService{S2}最后,我们可以启动客户端,再次用命令行选项告诉它如何命名服务联系。client -ORBInitRef NameService=corbaloc:iiop:localhost:8140/NameService{S3}{A35} CORBA的优点和D CORBA提供了几个好处。首先,可用于CORBA实现许多编程语言(如C语言,C,JAVA,COBOL,阿达,Smalltalk和Python,Tcl和Perl等)和许多操作系统(包括Windows,UNIX和大型机和嵌入式设备) 。并非所有的客户端 - 服务器技术可以索赔。例如,Microsoft技术(COM,DCOM和。NET)历来仅适用于Windows。 Java RMI的作品跨越多个操作系统,但它可用于在基于Java的应用。二,乘警时,远程调用,CORBA在网络上传输到一个紧凑的二进制格式的参数。这种紧凑的格式,节省网络带宽。此外,编组的二进制格式的参数所需的CPU开销也相当低。与此相反,一些较新的客户端 - 服务器技术,如SOAP,,成XML格式的元帅参数时,远程调用。 XML是非常详细的,所以它使用了大量的带宽,相当于CORBA的呼叫的带宽通常至少十倍以上。此外,基于SOAP服务器接收到一个请求时,它必须解析的XML中提取的参数数据。这样做需要大量的CPU时间。相比之下,可以封送参数和CORBA的二进制消息格式更加迅速。三,CORBA的已远超过十年左右,这意味着它的技术是相当稳定的,功能丰富的。当然,CORBA是不完美。其主要缺点是CORBA的权力和灵活性相对陡峭的学习曲线。所谓开放源码库{A36}简化了一些,但不是所有的,C和Java开发人员的学习曲线。{A37}进一步阅读你可以找到{A38} CORBA的概念的一个很好的概述。对于编写CORBA应用程序在C的详细信息,请阅读与C高级米尺亨宁和史蒂夫Vinoski CORBA编程。关于理论和基本面:分布式系统:概念和设计由乔治Coulouris,让Dollimore添Kindberg.nb​​
从国立大学远程教育的书籍和笔记 - UNED - 西班牙
{A39}致谢我想感谢他对这篇文章的草稿反馈的Progress软件夏兰麦克海尔。
关于作者:
中国我是一名编程爱好者,谢谢为我们提供一个学习和分享的平台。有什么问题。可以就本内容回复,我看到时。会尽量回复的。
评论会员:
时间:您好,我如何可以生成stub和skeleton?请回答我评论会员:
时间:。嗨
您必须使用包括在CORBA ORB的IDL编译器。它有好几个名字,如:idl2cpp,idl2java或IDL简单评论会员:
时间:我下载的源代码,然后builded。但我得到的错误〜〜〜致命错误C1083:无法打开包括文件:"OB / CORBAClient.h":没有这样的文件或目录〜〜这个样子。我怎样才能解决这个问题评论会员:
时间:您好,
指定路由的头在你的C IDE编译器选项评论会员:
时间:liusj2000:{S4}的希望您的帮助我飞会员4645675评论会员:
时间:我下载的是什么自称是源,我只是EXE项目称为crypt_service。有事吗?戴夫交叉
&桌面&网页开发&移动开发&数据库&多媒体&编程语言&平台,框架和库&编程通用&图形/设计&开发周期&一般阅读&第三方产品&作者资源&其他
快速解答标签
价值作最多2008年2月 VB大版内专家分月排行榜第一2003年4月 VC/MFC大版内专家分月排行榜第一2002年11月 VC/MFC大版内专家分月排行榜第一
2011年11月 VC/MFC大版内专家分月排行榜第二2008年3月 VB大版内专家分月排行榜第二2008年3月 硬件/嵌入开发大版内专家分月排行榜第二2003年4月 其他开发语言大版内专家分月排行榜第二2003年4月 VB大版内专家分月排行榜第二2003年3月 VB大版内专家分月排行榜第二
本帖子已过去太久远了,不再提供回复功能。TCP通信服务器端的工作流程如图7.8。
图 7.8 &TCP 通信服务器端的工作流程
从图7.8可以看出,在基于TCP通信的服务器端程序中,包含了两种socket,一种用于侦听客户端连接,我们称之为 ServerSocket;另一种用于和客户端通信,我们称之为PeerSocket,它不是程序自己建立的,而是由accept函数返回给程序的。之所以这样设立,是因为服务器端往往是同时和多个客户端进行通信。前面已经提过,TCP通信是依靠通信双方的全关联连接,因此服务器和每一个客户端都会建立一个全关联;而一个socket只能代表一个全关联,因此在socket设计中就由PeerSocket来代表与客户端之间的全关联关系,而ServerSocket只用于侦听客户端连接。MFC套接字类里相关的几个函数如下:
BOOL Create(
& & UINT nSocketPort = 0,int nSocketType = SOCK_STREAM,
& & long lEvent = FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE,
& & LPCTSTR lpszSocketAddress = NULL
该函数用于创建一个套接字并与某一端口绑定。参数如下:
nSocketPort:该套接字需要绑定的端口,如果为0,则由系统分配一个端口。
nSocketType:套接字类型,SOCK_STREAM表示TCP套接字,SOCK_DGRAM表示采用数据报(UDP)套接字。
lEvent:事件掩码,表示系统需要将哪些事件反馈到客户套接字上。默认是选择所有事件。
FD_READ:当有数据到达时,提示用户接受。
FD_WRITE:当有数据需要发送时,提示用户发送。
FD_OOB:当需要接受带外数据时,提示用户。
FD_ACCEPT:当用户进行连接时,提示用户接受用户连接。
FD_CONNECT:当连接完成时,提示用户。
FD_CLOSE:当套接字关闭时,提示用户。
lpszSocketAddress:如果该参数不为空,则表示将套接字绑定的网络地址字符串,如&128.56.22.8&。
函数返回值为0时表示端口已被占有,为1时表示套接字创建成功。
& & BOOL Accept(CAsyncSocket& rConnectedSocket,SOCKADDR* lpSockAddr = NULL,int*&lpSockAddrLen = NULL);
该函数用于接受客户端连接,并将连接套接字绑定到rConnectedSocket上。参数含义如下:
rConnectedSocket:是一个引用传递参数,用于获取和客户端建立连接的Socket。
lpSockAddr:指向SOCKADDR结构的一个指针,用于获取客户端地址。
lpSockAddrLen:整型指针,用于接收前面获取的SOCKADDR结构的真实长度。
BOOL Listen(int nConnectionBacklog = 5);
此函数用于启动系统侦听,等待用户连接。函数返回BOOL值,表示是否启动成功。参数如下:
nConnectionBacklog:表示可以同时等待连接的客户连接数。
首先,我们在工程里添加CServerSocket和CPeerSocket两个类,这两个类都是从CSocket类派生的。在Insert|Net Class里添加新类,如图7.9所示。使用同样方法在工程里添加CPeerSocket类。
由于MFC所封装的Socket类都是采用消息机制,因此我们可以不采用多线程的服务器编程模式,而只用添加消息映射函数实现客户/服务器网络程序。在前面我们已经谈到MFC的Socket类对TCP/IP通信的不同事件都有相应的处理函数。要完成通信,就必须继承CSocket类的相应处理函数,并添加我们自己的代码。
首先,我们在CServerSocket类里添加对客户端连接事件的处理函数OnAccept。打开ClassWizard,选择CServerSocket,在Messages列表框里选中OnAccept,然后单击Add Function按钮。如图7.10所示。
图 7.9 &加入新类 CServerSocket
图 7.10 &添加 OnAccept 函数
CServerSocket的OnAccept函数代码如下:
void CServerSocket::OnAccept(int nErrorCode){
& & CPeerSocket *peersocket=new CPeerSocket(); //创建新的PeerSocket
& & BOOL ok=Accept(*peersocket);&& //接受用户连接
& & if (!ok)&& //如果接受错误,则删除socket
& & CSocket::OnAccept(nErrorCode);
注意:由于调用Accept函数后,系统会将已经建立连接的套接字与传给Accept函数的socket变量绑定在一起,因此传给Accept函数的Socket变量不能是临时变量。用户必须保证在OnAccept函数返回时,该变量不会释放掉。在实际程序中,往往是用new操作符分配该变量或者使用其他全局池的方法。
要处理用户命令,还必须给CPeerSocket类添加接收事件处理函数OnReceive,添加方法和前面添加OnAccept函数是类似的,只是这时选择的类名是CPeerSocket。然后在OnReceive函数里调用Receive函数来接收用户数据。Receive函数格式如下:
& & int Receive(void* lpBuf,int nBufLen,int nFlags = 0);
lpBuf:是用于接收用户数据的缓冲区
nBufLen:表示缓冲区的大小
nFlags:标记位,只有标记位相同的数据才能被接收。
函数返回值为整数,表示实际接收的数据长度;如果返回值为-1,则表示套接字已关闭或者网络出现错误。可以通过GetLastError函数来获取错误号。
本文共2页: 上一页1

我要回帖

更多关于 cs1.6服务器客户端 的文章

 

随机推荐