朔州信息港
网络
当前位置:首页 > 网络

CCLI程序进程之间的通讯

发布时间:2019-06-20 06:16:04 编辑:笔名

  现在,把大型软件项目分解为一些相交互的小程序似乎变得越来越普遍,程序各部分之间的通讯可使用某种类型的通讯协议,这些程序可能运行在不同的机器上、不同的操作系统中、以不同的语言编写,但也有可能只在同一台机器上,实际上,这些程序可看成是同一程序中的不同线程。而本文主要讨论C++/CLI程序间的通讯,当然,在此是讨论进程间通讯,而不是络通讯。

  简介

  试想一个包含数据库查询功能的应用,通常有一个被称为服务端的程序,等待另一个被称为客户端程序发送请求,当接收到请求时,服务端执行相应功能,并把结果(或者错误信息)返回给客户端。在许多情况中,有着多个客户端,所有的请求都会在同一时间发送到同一服务端,这就要求服务端程序要更加高级、完善。

  在某些针对此任务的环境中,服务端程序可能只是众多程序中的一个程序,其他可能也是服务端或者客户端程序,实际上,如果我们的数据库服务端需要访问不存在于本机的文件,那么它就可能成为其他某个文件服务器的一个客户端。一个程序中可能会有一个服务线程及一个或多个客户线程,因此,我们需小心使用客户端及服务端这个术语,虽然它们表达了近似的抽象含义,但在具体实现上却大不相同。从一般的观点来看,客户端即为服务端所提供服务的"消费者",而服务端也能成为其他某些服务的客户端。

  服务端套接字

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

  例1:

  using namespace System;

  using namespace System::IO;

  using namespace System::Net;

  using namespace System::Net::Sockets;

  int main(arrayString^^ 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提供,并且需要在生成期间引用l程序集。另外,因为通过套接字的通讯涉及到流,所以还要用到System:IO机制。

  当程序执行时,服务端需要知道其用来监听客户端连接请求的端口号,在此,这个整数值通过命令行参数提供。一般来说,端口号在范围内,而保留给特定的用途,因此,服务端可用的端口号就为。

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

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

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

  套接字默认以阻塞模式创建,如标号7中所示,这意味着,它会一直等待连接请求。

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

  在这个简单的例子中,我们只关心请求连接的个客户端,一旦连接上了,便可关闭此监听连接请求的套接字(参见标号9)。

  在标号中,我们用近连接的套接字,建立了一个NetworkStream,连同两个读写函数一起,便可以从套接字接收请求,并返回结果。

  服务端在此无限循环,读入一对整数,计算它们的和,并把结果返回给客户端。当服务端探测到输入流中的文件结束标志时(由客户端关闭了套接字),会抛出EndOfStreamException异常,并关闭I/O流和套接字,服务结束。

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

  为何要捕捉IOException异常的原因在标号17中,在此是为了处理客户端在关闭套接字之前的过早结束。

芪斛楂颗粒的作用
芪斛楂颗粒
两岁宝宝积食怎么办
友情链接
宝宝积食拉肚子的症状 小孩脾虚如何调理 小孩感冒吃什么药 合肥有哪些中医老年病科医院 黄山有哪些肝病科医院 呼和浩特有哪些中医儿科医院 包头有哪些手外科医院 呼伦贝尔有哪些肝炎医院 巴彦淖尔有哪些中西医结合科医院 乌兰察布有哪些医学影像科医院 昌吉口腔科医院哪家好 阳泉有哪些牙体牙髓科医院 昌吉整形科医院哪家好 长治有哪些内科医院 巴州耳鼻喉医院哪家好 克州神经内科医院哪家好 晋中有哪些IMCC医院 运城有哪些其它科室医院 克州功能神经外科医院哪家好 喀什中医呼吸科医院哪家好 忻州有哪些高压氧科医院 吕梁有哪些中医免疫内科医院 宝鸡有哪些耳鼻喉医院 五家渠中医感染内科医院哪家好 东方碎石中心医院哪家好 白沙器官移植医院哪家好 果洛小儿泌尿科医院哪家好 白城有哪些特诊科医院 江苏二丙医院哪家好 百色有哪些IMCC医院 玉溪有哪些其它科室医院 楚雄有哪些眼底医院 六安二丙医院哪家好 乌海二丙医院哪家好 忻州一乙医院哪家好 文山有哪些角膜科医院 文山有哪些中医神经内科医院 吉林其他医院哪家好 大理有哪些整形科医院 黔西三乙医院哪家好 银川二乙医院哪家好 定安其他医院哪家好 金昌有哪些其他内科医院 天水有哪些口腔急诊科医院 儋州医院哪家好 医学影像学 平凉有哪些乳腺外科医院 瘦腰 平凉有哪些耳鼻喉医院 唇部整形 酒泉有哪些综合医院 定西有哪些特诊科医院 腋臭整形 增肌经验谈 动物咬伤 甘南有哪些中医骨科医院 三从四德 小儿心外科 功血 秋季护肤 丰胸药膳 宝宝拉肚子怎么办小组话题 陕西有哪些五官科医院 江西有哪些医疗美容医院 广西有哪些介入医学科医院 西藏有哪些其它科室医院 宁夏有哪些特诊科医院 广州有哪些心血管内科医院 广州有哪些中医血液科医院 韶关有哪些消化内科医院 江门有哪些遗传咨询科医院 湛江有哪些理疗科医院 肇庆有哪些内科医院 河源有哪些老年病科医院 河源有哪些其他外科医院 揭阳有哪些运动医学科医院 淄博有哪些生殖医学科医院 枣庄有哪些心血管内科医院 潍坊有哪些超声科医院 泰安有哪些运动医学科医院 泰安有哪些实验中心医院 泰安有哪些眼科医院 常州有哪些心胸外科医院 常州有哪些干部诊疗科医院 镇江有哪些骨关节科医院 泰州有哪些特诊科医院 湖州有哪些手外科医院 舟山有哪些遗传咨询科医院 丽水有哪些放射科医院 黄石有哪些其他医院 荆门有哪些高压氧科医院 神农架有哪些皮肤科医院 神农架有哪些复杂先心病医院 平顶山有哪些骨外科医院 新乡有哪些屈光医院 绵阳有哪些中医老年病科医院