Socket类

初始化

  1. public socket (AddressFamily addressFamily,SocketType sockettype,ProtocolType protocolType)
  2. public void Bind(EndPoint localEP); // 绑定端口
  3. public void Listen(int backlog); // 监听,设置最大连接数
  4. public bool IsBound { get; } // 端口是否绑定成功
  5. public AddressFamily AddressFamily { get; }
  6. public SocketType SocketType { get; }
  7. public ProtocolType ProtocolType { get; }
  8. public EndPoint LocalEndPoint { get; }
  9. public EndPoint RemoteEndPoint{ get; }

(1)AddressFamily:socket解析地址的寻址方案(地址族)

  • InterNetwork:IPV4地址;
  • InterNetworkV6:IPV6地址;

(2)SocketType:socket类型

  • Raw:支持基础传输协议访问;
  • Stream:流式Socket,支持可靠、双向、面向连接的字节数据流;
  • Dgram:数据包式Socket,支持数据报,不可靠消息、面向无连接的数据报;
  • Rdm:支持无连接、面向消息、以可靠方式发送的消息,保留数据中的消息边界,消息会依次到达,不会重复;

(3)ProtocolType:socket支持的网络协议

  • IP:网际协议;
  • TCP:传输控制协议;
  • UDP:用户数据报协议;

(4)监听连接:3种方式监听客户端连接

  • Accept()方式:同步阻塞;
  • AcceptAsync()方式:异步;
  • BeginAccept()方式:异步; 

关闭回收

  1. public void Shutdown(SocketShutdown how); // 禁用某Socket上的发送和接收
  2. public void Close(); // 关闭Socket连接并释放所有关联的资源
  3. public void Dispose(); // 释放由Socket类的当前实例占用的所有资源
  4. protected virtual void Dispose(bool disposing); // 释放由Socket使用的非托管资源和托管资源

(1)Shutdown()

若使用面向连接的Socket,须先调用Shutdown方法,才能关闭Socket。确保关闭已连接的Socket前,已发送和接收该Socket上的所有数据,调用Close方法释放与Socket关联的所有托管资源和非托管资源。关闭Socket后不要尝试重用它。 

(2)Close()

(3)Socket对象的优雅关闭 

状态信息

  1. public bool Blocking { get; set; } // 指示Socket是否处于阻止模式
  2. public bool Connected { get; } // 指示Socket上次Send/Receive操作时连接到远程主机时的状态
  3. public int Available { get; } // 获取已经从网络接收且可供读取的数据量
  4. public bool Poll(int microSeconds, SelectMode mode); // 确定Socket的状态
  5. public static void Select(IList checkRead, IList checkWrite, IList checkError, int microSeconds); // 确定1个或多个Socket的状态

(1)Connected

(2)Available

(3)Poll()

(4)Select()

检测客户端Socket是否已关闭(可读数据检测)

 a.利用Available属性 + Receive()方法

  • 客户端直接关闭,Available属性返回0,但不会引发异常;
  • 客户端通过shutdown-close关闭Socket,Available属性返回0,但不会引发异常;

 b.利用poll()方法 + Receive()方法

  • 客户端直接关闭,poll()方法直接引发异常;
  • 客户端通过shutdown-close关闭Socket,Receive()立即返回0而不会阻塞(若Socket连接正常,Receive()会阻塞);  

同步方式

  1. public void Connect(EndPoint remoteEP); // 建立与远程主机的连接
  2. public void Disconnect(bool reuseSocket); // 关闭Socket连接并允许重用Socket
  3. public Socket Accept(); // 为新建连接创建新的Socket
  4. public int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode); // 将数据发送到连接的Socket的发送缓冲区
  5. public int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode); // 从绑定的Socket接收数据存入接收缓冲区

(1)Accept()

(2)Send()

(3)Receive()

在面向连接的Socket中,如果没有可读取的数据,Receive方法将一直处于阻止状态、直到数据可用(除非使用Socket.ReceiveTimeout设置了超时值),此时Receive方法会读取所有可用的数据,直到达到缓冲区的大小为止。如果远程主机使用Shutdown方法关闭了Socket连接,并且所有可用数据均已收到,则Receive方法将立即完成并返回0字节。  

APM:Begin/End

  1. public IAsyncResult BeginAccept(AsyncCallback callback, object state); // 开始一个异步操作接受一个传入的连接尝试
  2. public Socket EndAccept(IAsyncResult asyncResult); // 异步接受传入的连接尝试,创建新的Socket与远程主机通信
  3. public IAsyncResult BeginConnect(Xxx, AsyncCallback callback, object state); // 开始一个对远程主机连接的异步请求
  4. public void EndConnect(IAsyncResult asyncResult); // 结束挂起的异步连接请求
  5. public IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback callback, object state); // 开始异步请求从远程终结点断开连接
  6. public void EndDisconnect(IAsyncResult asyncResult); // 结束挂起的异步断开连接请求
  7. public IAsyncResult BeginSend(Xxx, AsyncCallback callback, object state); // 开始将数据异步发送到连接的Socket
  8. public int EndSend(IAsyncResult asyncResult); // 结束挂起的异步发送
  9. public IAsyncResult BeginReceive(Xxx, AsyncCallback callback, object state); // 开始从连接的Socket中异步接收数据
  10. public int EndReceive(IAsyncResult asyncResult); // 结束挂起的异步接收

TAP

监听

  1. IPEndPoint localEndPoint = new IPEndPoint(_ipAddress, _port);
  2. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// Create a TCP/IP socket.
  3. try {
  4. listener.Bind(localEndPoint);// Bind the socket to the local endpoint and listen for incoming connections.
  5. listener.Listen(10); //最大监听数
  6. while (true) {
  7. // Set the event to nonsignaled state.
  8. allDone.Reset();
  9.  
  10. // Start an asynchronous socket to listen for connections.
  11. Console.WriteLine("Waiting for a connection");
  12. StateObject state = new StateObject();
  13. listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
  14.  
  15. // Wait until a connection is made before continuing.
  16. allDone.WaitOne();
  17. }
  18. } catch (Exception e) { }

数据接收流向: StartListening --> AcceptCallback --> ReceiveCallback --> 主处理

发送流向: Send --> SendCallback -->发送完成

参考1参考2

APM模式、TAP模式虽然解决了Socket的并发问题,但在大并发下会有较大性能问题,生产IAsyncResult等对象导致垃圾对象创建与回收。提供一个过度方法 BufferManager 仅供参考:socket发送接收缓冲区工具类

微软从.Net3.5提供了高性能异步Socket实现类

SAEA:SocketAsyncEventArgs类

表示异步套接字操作,主要用于高性能网络服务器应用程序,避免在异步套接字I/O量非常大时发生重复的对象分配和同步。

  1. public bool ConnectAsync(SocketAsyncEventArgs e); // 开始一个连接远程主机的异步请求
  2. public static void CancelConnectAsync(SocketAsyncEventArgs e); // 取消一个对远程主机连接的异步请求
  3. public bool DisconnectAsync(SocketAsyncEventArgs e); // 开始异步请求从远程终结点断开连接
  4. public bool AcceptAsync(SocketAsyncEventArgs e); // 开始一个异步操作接受一个传入的连接尝试
  5. public bool SendAsync(SocketAsyncEventArgs e); // 将数据异步发送到连接的Socket对象
  6. public bool ReceiveAsync(SocketAsyncEventArgs e); // 开始一个异步请求从连接的Socket对象中接收数据

(1)返回值

  • 如果I/O操作挂起,返回true,操作完成时,引发e参数的SocketAsyncEventArgs.Completed事件;
  • 如果I/O操作同步完成,返回false,这种情况下,不会引发e参数的SocketAsyncEventArgs.Completed事件,并且可能在方法调用返回后立即检查作为参数传递的e对象以检索操作的结果;

使用步骤

  • 分配一个新的SocketAsyncEventArgs上下文对象,或者从应用程序池中获取一个空闲的此类对象
  • 将该上下文对象的属性设置为要执行的操作(eg:完成回调方法、数据缓冲区、缓冲区偏移量以及要传输的最大数据量)
  • 调用适当的异步套接字方法xxxAsync()启动异步操作:
    • 如果方法xxxAsync()返回true,则在回调中查询上下文属性来获取完成状态
    • 如果方法xxxAsync()返回false,则说明操作是同步完成的,可以查询上下文属性来获取操作结果
  • 将该上下文重用于另一个操作:放回应用程序池中,或者丢弃

实例实战

参考1参考2

参考

C# - 网络编程 之 Socket的更多相关文章

  1. java基础-网络编程(Socket)技术选型入门之NIO技术

    java基础-网络编程(Socket)技术选型入门之NIO技术 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传统的网络编程 1>.编写socket通信的MyServer ...

  2. python 网络编程:socket(二)

    上节地址:Python网络编程:socket 一.send和sendall区别 send,sendall         ret = send('safagsgdsegsdgew') #send 发送 ...

  3. Linux高并发网络编程开发——10-Linux系统编程-第10天(网络编程基础-socket)

    在学习Linux高并发网络编程开发总结了笔记,并分享出来.有问题请及时联系博主:Alliswell_WP,转载请注明出处. 10-Linux系统编程-第10天(网络编程基础-socket) 在学习Li ...

  4. 网络编程与socket套接字

    网络编程与socket套接字 传输层 PORT协议 port是一种接口,数据通过它在计算机和其他设备(比如打印机,鼠标,键盘或监视器)之间,网络之间和其他直接连接的计算机之间传递 TCP协议 ​ 传输 ...

  5. linux网络编程-(socket套接字编程UDP传输)

    今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中, ...

  6. 浅谈TCP/IP网络编程中socket的行为

    我认为,想要熟练掌握Linux下的TCP/IP网络编程,至少有三个层面的知识需要熟悉: 1. TCP/IP协议(如连接的建立和终止.重传和确认.滑动窗口和拥塞控制等等) 2. Socket I/O系统 ...

  7. iOS 网络编程:socket

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  8. iOS网络编程笔记——Socket编程

    一.什么是Socket通信: Socket是网络上的两个程序,通过一个双向的通信连接,实现数据的交换.这个双向连路的一端称为socket.socket通常用来实现客户方和服务方的连接.socket是T ...

  9. python 网络编程(Socket)

    # from wsgiref.simple_server import make_server## def RunServer(environ,start_response):# start_resp ...

  10. 网络编程,socket

    1.网络编程 网络: TCP/IP 彼此之间遵守协议和规范!之间才能产生通信! IP: 每个人都有自己的身份证号! 用来标识我们网络中每一台计算机! IP地址= 网络地址 +主机地址 网络地址 :标识 ...

随机推荐

  1. 终端mysql Operation not permitted错误解决方案

    前言 前段时间装mysql,就遇到了ln: /usr/bin/mysql: Operation not permitted的错误,网上好多方法都过时了,下边是我的解决方法 原因 这是因为苹果在OS X ...

  2. git-2.10.2-64-bit介绍&&git下载&&git安装教程

    Git介绍 分布式:Git系统是一个分布式的系统,是用来保存工程源代码历史状态的命令行工具. 保存点:Git的保存点可以追踪源码中的文件, 并能得到某一个时间点上的整个工程项目的状态:可以在该保存点将 ...

  3. 文件随机读写专用类——RandomAccessFile

     RandomAccessFile类可以随机读取文件,但是在测试中并不好用;File类可以测试文件存不存在,不存在可以创建文件;FileWriter类可以对文件进行重写或者追加内容;FileReade ...

  4. 去IOE的一点反对意见以及其他

    某天在机场听见两老板在聊天,说到他们目前销售的报表老跟不上的问题,说要请一个人,专门合并和分析一些发过来的excel表格,我真想冲上去说,老板,你需要的是一个信息处理的系统,你需要咨询么.回来一直耿耿 ...

  5. SymmetricDS 快速和灵活的数据库复制

    开始谈谈开源的SymmetricDS,谈谈实际使用中,遇到的一些问题和解决办法.持续更新: SymmetricDS 快速和灵活的数据库复制 实际使用 和 埋过的坑 (一)知识篇 SymmetricDS ...

  6. 用SecureCRT连接虚拟机中的Linux系统(Ubuntu)

    今天突然练习linux命令行的时候,想在window中联系linux命令行.经过一番dudu找到了一个不错的的工具(SecureCRT--意思安全)就是用SSH链接linux主机.推荐大家使用.毕竟w ...

  7. Java泛型的历史

    为什么Java泛型会有当前的缺陷? 之前的章节里已经说明了Java泛型擦除会导致的问题,C++和C#的泛型都是在运行时存在的,难道Java天然不支持“真正的泛型”吗? 事实上,在Java1.5在200 ...

  8. Nodejs之MEAN栈开发(八)---- 用户认证与会话管理详解

    用户认证与会话管理基本上是每个网站必备的一个功能.在Asp.net下做的比较多,大体的思路都是先根据用户提供的用户名和密码到数据库找到用户信息,然后校验,校验成功之后记住用户的姓名和相关信息,这个信息 ...

  9. CSharpGL(7)对VAO和VBO的封装

    CSharpGL(7)对VAO和VBO的封装 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码中包含10多个独立的Demo,更适合入门参考 ...

  10. ABP源码分析二十二:Navigation

    MenuDefinition:封装了导航栏上的主菜单的属性. MenuItemDefinition:封装了主菜单的子菜单的属性.子菜单可以引用其他子菜单构成一个菜单树 UserMenu/UserMen ...