当前位置:七道奇文章资讯编程技术VC/C++编程
日期:2011-03-22 13:56:00  来源:本站整理

C++/CLI程序进程之间的通讯[VC/C++编程]

赞助商链接



  本文“C++/CLI程序进程之间的通讯[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
目前,把大型软件项目分化为一些相交互的小程序仿佛变得越来越广泛,程序各部份之间的通讯可以利用某种范例的通讯协议,这些程序大概运行在差别的机械上、差别的操作系统中、以差别的语言编写,但也有大概只在同一台机械上,实际上,这些程序可当作是同一程序中的差别线程.而本文主要谈论C++/CLI程序间的通讯,当然,在此是谈论进程间通讯,而不是网络通讯.

  简介

  试想一个包含数据库查询功效的利用,普通有一个被称为服务端的程序,等候另一个被称为客户端程序发送恳求,当接纳到恳求时,服务端履行呼应功效,并把后果(大概错误信息)返回给客户端.在很多情形中,有着多个客户端,全部的恳求城市在同一时间发送到同一服务端,这就要求服务端程序要越发高级、完善.

  在某些针对此任务的环境中,服务端程序大概只是众多程序中的一个程序,其他大概也是服务端大概客户端程序,实际上,假如我们的数据库服务端需求拜候不存在于本机的文件,那么它便大概成为其他某个文件服务器的一个客户端.一个程序中大概会有一个服务线程及一个或多个客户线程,因此,我们需当心利用客户端及服务端这个术语,固然它们表达了近似的抽象含义,但在具体实现上却大不相同.从普通的概念来看,客户端即为服务端所供应服务的"消费者",而服务端也能成为其他某些服务的客户端.

  服务端套接字

  让我们从一个具体有代表性的服务端程序开始(请看例1),此程序等候客户端发送一对整数,把它们相加上后返回后果给客户端.

  例1:

using namespace System;
using namespace System::IO;
using namespace System::Net;
using namespace System::Net::Sockets;

int main(array<String^>^ argv)
{
if (argv->Length != 1)
{
Console::WriteLine("Usage: Server port");
Environment::Exit(1);
}

int port = 0;

try
{
port = Int32::Parse(argv[0]);
}
catch (FormatException^ e)
{
Console::WriteLine("Port number {0} is ill-formed", argv[0]);
Environment::Exit(2);
}

/*1*/ if (port < IPEndPoint::MinPort || port > IPEndPoint::MaxPort)
{
Console::WriteLine("Port number must be in the range {0}-{1}",
IPEndPoint::MinPort, IPEndPoint::MaxPort);
Environment::Exit(3);
}

/*2*/ IPAddress^ ipAddress =
Dns::GetHostEntry(Dns::GetHostName())->AddressList[0];
/*3*/ IPEndPoint^ ipEndpoint = gcnew IPEndPoint(ipAddress, port);

/*4*/ Socket^ listenerSocket = gcnew Socket(AddressFamily::InterNetwork,
SocketType::Stream, ProtocolType::Tcp);

/*5*/ listenerSocket->Bind(ipEndpoint);

/*6*/ listenerSocket->Listen(1);
/*7*/ Console::WriteLine("Server listener blocking status is {0}",
listenerSocket->Blocking);

/*8*/ Socket^ serverSocket = listenerSocket->Accept();
Console::WriteLine("New connection accepted");
/*9*/ listenerSocket->Close();

/*10*/ NetworkStream^ netStream = gcnew NetworkStream(serverSocket);
/*11*/ BinaryReader^ br = gcnew BinaryReader(netStream);
/*12*/ BinaryWriter^ bw = gcnew BinaryWriter(netStream);

try
{
int value1, value2;
int result;

while (true)
{
/*13*/ value1 = br->ReadInt32();
/*14*/ value2 = br->ReadInt32();
Console::Write("Received values {0,3} and {1,3}",
value1, value2);

result = value1 + value2;
/*15*/ bw->Write(result);
Console::WriteLine(", sent result {0,3}", result);
}
}
/*16*/ catch (EndOfStreamException^ e)
{
}
/*17*/ catch (IOException^ e)
{
Console::WriteLine("IOException {0}", e);
}

/*18*/ serverSocket->Shutdown(SocketShutdown::Both);
/*19*/ serverSocket->Close();
/*20*/ netStream->Close();
Console::WriteLine("Shutting down server");
}


  此处与套接字相关的功效由命名空间System::Net和System::Net::Sockets供应,并且需求在生成期间引用System.dll程序集.别的,因为通过套接字的通讯触及到流,所以还要用到System:IO机制.

  当程序履行时,服务端需求知道其用来监听客户端衔接恳求的端口号,在此,这个整数值通过号令行参数供应.普通来说,端口号在0-65535范围内,而0-1023保存给特定的用处,因此,服务端可用的端口号就为1024-65535.

  在标号1中,通过IPEndPoint类中的MinPort和MaxPort这两个大众静态字段,便可得到特定系统上可用的端口范围.

  而在标号2中,可得到我们自己的主机名,并解析到一个IpHostEntry,可从中获得本机的IP地址.接下来在标号3中,用IP地址和端口号成立了一个IPEndPoint对象,其可为某个衔接供应某种服务.

  在标号4中,成立了一个Internet传输服务托管版本的套接字,一旦它被成立,就应通过Bind函数(标号5)绑定到一个特定的端点.接下来,套接字声明其已经开始服务,并监听衔接恳求(标号6).传送给Listen的参数表明了恳求行列中衔接挂起的长度,因为我们只有一个客户端,所以在此1就充足了.

  套接字默许以阻塞情势成立,如标号7中所示,这意味着,它会一向等候衔接恳求.

  当从客户端接纳到衔接恳求时,阻塞的套接字就会被唤醒,通过调用Accept(如标号8),承受恳求并成立另一个套接字,并通过此套接字来与客户端通讯.我们看到,此时的服务端有两个套接字:一个用于监听客户衔接恳求,而另一个用于与衔接的客户端通讯.当然,一个服务端在同一时间,可与多个客户端举行衔接,且每个客户端都有一个套接字.

  在这个简单的例子中,我们只关心恳求衔接的第一个客户端,一旦衔接上了,便可关闭此监听衔接恳求的套接字(拜见标号9).
在标号10-12中,我们用近来衔接的套接字,成立了一个NetworkStream,连同两个读写函数一同,便可以从套接字接纳恳求,并返回后果.
服务端在此无限循环,读入一对整数,计算它们的和,并把后果返回给客户端.当服务端探测到输入流中的文件完毕标志时(由客户端关闭了套接字),会抛出EndOfStreamException非常,并关闭I/O流和套接字,服务完毕.

  标号18中的Socket::ShutDown调用将同时关闭套接字上的接纳和发送功效,因为我们的服务端只需告之一个客户端它的关闭,所以此函数调用有点多余,但是,在服务端要过早地完毕的某些情形下,这种做法还是有效的.

  为什么要捕捉IOException非常的缘由在标号17中,在此是为了处理客户端在关闭套接字之前的过早完毕.
  以上是“C++/CLI程序进程之间的通讯[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:

  • win8 Could not load type System.ServiceModel.Activation.HttpModule 错误办理筹划
  • 利用Javascript实现网页水印(非图片水印)
  • 在Windows7中将U盘用BitLocker加密的操作步骤
  • rs.open和conn.execute辨别
  • 不用注册机破解Photoshop CS5 每次都需求重新输入注册码
  • CSS网页筹划25个实用小本领
  • CSS3教程:利用@font-face实现本性化字体
  • 办理Windows提醒0xc000009内存错误的办法
  • PHP的chm手册打不开怎么办
  • 关于SQL中CTE(公用表表达式)(Common Table Expression)的总结
  • mysql #1062 –Duplicate entry ''1'' for key ''PRIMARY''
  • SQL Server中利用Linkserver衔接Oracle的办法
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .