在.NET上编写网络服务深入都有2,3年了,而这些时间时如何在.NET里实现网络服务积累了一些经验.在接下来的时间里会把这方面的经验通过博客的方式分享出来.而这一章主要是讲解在如果提高服务连接接入的效率,从而让服务连接接入的并发量有高吞吐的性能.

其实.NET提供了一个非常强大的网络模型给我们使用,而我们只需要把这个模型用好那基于是不存在多大问题.不过由于很多开发人员对这方面并没有了解和深入所以感觉.Net编写一个高效能的服务比较因难.下面通过不同的示例来描述问题的所在从而避免这些问题的出现,让编写的服务更高效.

示例1

  try {listener.Bind(localEndPoint);listener.Listen(10);// Start listening for connections.while (true) {Console.WriteLine("Waiting for a connection...");// Program is suspended while waiting for an incoming connection.Socket handler = listener.Accept();data = null;// An incoming connection needs to be processed.while (true) {bytes = new byte[1024];int bytesRec = handler.Receive(bytes);data += Encoding.ASCII.GetString(bytes,0,bytesRec);if (data.IndexOf("<EOF>") > -1) {break;}}// Show the data on the console.Console.WriteLine( "Text received : {0}", data);// Echo the data back to the client.byte[] msg = Encoding.ASCII.GetBytes(data);handler.Send(msg);handler.Shutdown(SocketShutdown.Both);handler.Close();}} catch (Exception e) {Console.WriteLine(e.ToString());}

这是从MSDN得到的一个服务端示例的代码地址来源http://msdn.microsoft.com/en-us/library/6y0e13d3(v=vs.110).aspx以上代码说实话真没多大的参考意义,不过作为一个演示如何构建一个服务监听那还是起到作用;用在服务器应用上是完全不可行,因为这只会导致会话串行,同时只能处理一个.接下来在网上找一个支持连接并发的示例看一下

示例2

namespace SocketServer
{class Program{private static byte[] result = new byte[1024];private static int myProt = 8885;   //端口static Socket serverSocket;static void Main(string[] args){//服务器IP地址IPAddress ip = IPAddress.Parse("127.0.0.1");serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);serverSocket.Bind(new IPEndPoint(ip, myProt));  //绑定IP地址:端口serverSocket.Listen(10);    //设定最多10个排队连接请求Console.WriteLine("启动监听{0}成功", serverSocket.LocalEndPoint.ToString());//通过Clientsoket发送数据Thread myThread = new Thread(ListenClientConnect);myThread.Start();Console.ReadLine();}/// <summary>/// 监听客户端连接/// </summary>private static void ListenClientConnect(){while (true){Socket clientSocket = serverSocket.Accept();clientSocket.Send(Encoding.ASCII.GetBytes("Server Say Hello"));Thread receiveThread = new Thread(ReceiveMessage);receiveThread.Start(clientSocket);}}/// <summary>/// 接收消息/// </summary>/// <param name="clientSocket"></param>private static void ReceiveMessage(object clientSocket){Socket myClientSocket = (Socket)clientSocket;while (true){...int receiveNumber = myClientSocket.Receive(result);Console.WriteLine("接收客户端{0}消息{1}", myClientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result, 0, receiveNumber));}}}
}

以上示例可以接受多个连接同时进行处理,但缺点是非常明显如果服务支撑的连接数比较大的情况那这种方式是不可行.你想象一下如果这个服务端要支撑1W,3W或者10W连接的情况那需要开多少个线程去处理这些连接呢,即使可以这样做那线程的开销也足够让服务器受的了.接下来看MSDN提供的异步示例

示例3

while (true){        // Set the event to nonsignaled state.allDone.Reset();// Start an asynchronous socket to listen for connections.Console.WriteLine("Waiting for a connection...");listener.BeginAccept( new AsyncCallback(AcceptCallback),listener );// Wait until a connection is made before continuing.allDone.WaitOne();}public static void AcceptCallback(IAsyncResult ar) {// Signal the main thread to continue.allDone.Set();// Get the socket that handles the client request.Socket listener = (Socket) ar.AsyncState;Socket handler = listener.EndAccept(ar);// Create the state object.StateObject state = new StateObject();state.workSocket = handler;handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReadCallback), state);}

这个示例来源于http://msdn.microsoft.com/en-us/library/6y0e13d3(v=vs.110).aspx,其实这个代码已经非常高效的体现我们在编写服务的时候如何实现一个接入监听.此示例用在应用开发上完全胜任的.

改进

以上示例3已经提供非常不错的代码,那是否可以进行一些规范的改进呢.其实在过往的经验中来看是可以,首先我们了解.NET有两种线程,一种是我们常用的而别一种则是IO线程.其实用一些测试工具可以看到AcceptCallback是由IO线程回调,那我们希望回调线程更快速度的释放出来,那我们需要做一些隔离上的规划.其实在很多范例代码中都是一连串地把事件做完,接入->接收->发送.这样一个连贯性的代码实现导致后其线程资源的控制和规划就变得非常因难.

从代码设计可以通过队列把回调线程需要的工作隔离出来,可以让回调线程更快的归队来处理其接接入的工作.当隔离后即使以后连接接入需要加一些逻辑控制也不会影响回调线程的快速回归.这样就可以让整个异步线程资源更高效.

 public static void AcceptCallback(IAsyncResult ar) {// Signal the main thread to continue.allDone.Set();// Get the socket that handles the client request.Socket listener = (Socket) ar.AsyncState;Socket handler = listener.EndAccept(ar);Queue.Enqueue(handler);}

总结

其实队列分离和控制在整个网络通讯实施过程会经常用到,其主要作是处理资源的分块和线程资源控制.毕竟任何一台服务器的资源都是有限的,如何分配线程资源给不同的任何来完成工作是非常重要,毕竟大量线程的开销会对系统造成比较大的压力.

.NET Socket服务编程之-高效连接接入编相关推荐

  1. Java:socket服务端,socket服务端支持多连接,socket客户端,socket客户端支持发送和接受

    一.Java之socket服务端 新建一个Java工程 命名 给他先创建一个类 在类里面我们做一个main 这里面也需要,创建套接字,IP号,端口号 但是java中有一个类         Serve ...

  2. Socket网络编程(2)--服务端实现

    中秋了,首先祝大家中秋快乐,闲着无事在家整一个socket的聊天程序,有点仿QQ界面,就是瞎折腾,不知道最后是不是能将所有功能实现. 如果你对socket不了解,请看这篇文章:http://www.c ...

  3. c java socket编程_java+swing C/s模式的socket编程与长短连接

    java+swing C/s模式的socket编程与长短连接 什么是socket 长连接与短连接 所谓长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要 ...

  4. 1、Socket网络编程之建立Server、Client连接

    从今天开始,攻坚socket网络编程,会写一大堆学习记录哦! 基于C/S结构,socket网络编译便不可或缺Server和Client. 目录 编译阶段: 测试阶段: 编译阶段: 首先创建一个项目,命 ...

  5. 使用SuperSocket打造逾10万长连接的Socket服务

    使用SuperSocket打造逾10万长连接的Socket服务 原文:使用SuperSocket打造逾10万长连接的Socket服务 SuperSocket 是一个轻量级, 跨平台而且可扩展的 .Ne ...

  6. Java之socket网络编程

    socket网络编程 文章目录 socket网络编程 一.网络编程概述 二.网络通信要素概述 三.IP和端口号 四.网络协议 五.TCP网络编程 六.UDP网络编程 一.网络编程概述 网络编程的目的 ...

  7. Linux Socket网络编程UDP、TCP 阻塞与非阻塞 断线重连机制

    三种非阻塞模式的方法: (1) fcntl函数 int Mode = fcntl(sockfd, F_GETFL, 0);       //获取文件的Mode值     fcntl(sockfd, F ...

  8. DotNET(C#) Socket基本编程 (1)

    Socket基本编程 服务端: using System.Net; using System.Net.Sockets; using System.Text; using System.Threadin ...

  9. Linux C++/Java/Web/OC Socket网络编程

    一,Linux C++ Socket网络编程 1.什么是TCP/IP.UDP? TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制 ...

最新文章

  1. 在Linux上使用图形界面的GitHub Desktop
  2. Kubernetes — 调度系统
  3. python语言用途-Python在每个行业的用处
  4. 5.PHP与Web页面交互
  5. (转)Linux环境变量的设置和查看方法
  6. 关于测试用例的一些思考
  7. 云服务器的优点和缺点_为什么要使用云计算? 的优点和缺点
  8. 读书笔记:《一生的计划》
  9. python kmeans聚类_python机器学习之k-means聚类算法(1)
  10. 批处理文件中获取当前所在路径的几种方法,以及写文件到txt
  11. rr与hr_rr指标:HR和RR的区别
  12. 三维GIS引擎平台设计
  13. Pillow图像处理
  14. 33. Prometheus-报警-通知模板示例
  15. 线性回归模型 —— 普通最小二乘法(OLS)推导与python实现
  16. mac os 触摸屏_为什么没有出现触摸屏Mac
  17. 饥荒联机版服务器搭建过程--采取官网文档的方法
  18. 谈谈自己对线性最小二乘和非线性最小二乘之间关系的理解~
  19. 清理Ubuntu虚拟机磁盘空间
  20. 色差计算(颜色之间的相似度计算)

热门文章

  1. 数据scale过程用model更方便,可以保存到本地
  2. 科大讯飞和百得思维_最佳辩手陈铭力荐 讯飞智能学习机让学习不再难
  3. 【存储知识学习】第五章-5.4虚拟磁盘和5.5卷管理层-《大话存储》阅读笔记
  4. 《系统集成项目管理工程师》必背100个知识点-53项目团队建设的五个阶段及其特点...
  5. Winform中使用FileStream读取文件后,继续操作提示:it is being used by anothor process
  6. AndroidStudio打开新项目后解决下载某版本gradle慢的问题
  7. gRPC中Java和node进行异构通信-互为客户端和服务端
  8. VS开发C#窗体应用时怎样设置窗体属性
  9. Navicat向sqlserver中插入数据时提示:当 IDENTITY_INSERT 设置为 OFF 时,不能向表中的标识列插入显式值
  10. 谷歌浏览器怎样通过检查验证图片路径问题