详解C# Socket异步通信实例_C#教程

TCPServer 

1、使用的通讯通道:socket

2、用到的基本功能:

①Bind,

②Listen,

③BeginAccept

④EndAccept

⑤BeginReceive 

⑥EndReceive

3、函数参数说明

 Socket listener = new Socket(AddressFamily.InterNetwork,

      SocketType.Stream, ProtocolType.Tcp);

新建socket所使用的参数均为系统预定义的量,直接选取使用。

listener.Bind(localEndPoint);

localEndPoint 表示一个定义完整的终端,包括IP和端口信息。

//new IPEndPoint(IPAddress,port)

//IPAdress.Parse("192.168.1.3")

listener.Listen(100);

监听

  listener.BeginAccept(

          new AsyncCallback(AcceptCallback),

          listener);

AsyncCallback(AcceptCallback),一旦连接上后的回调函数为AcceptCallback。当系统调用这个函数时,自动赋予的输入参数为IAsyncResoult类型变量ar。

 listener,连接行为的容器。

Socket handler = listener.EndAccept(ar);

完成连接,返回此时的socket通道。

handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,

      new AsyncCallback(ReadCallback), state);

接收的字节,0,字节长度,0,接收时调用的回调函数,接收行为的容器。

========

容器的结构类型为:

public class StateObject
{
  // Client socket.
  public Socket workSocket = null;
  // Size of receive buffer.
  public const int BufferSize = 1024;
  // Receive buffer.
  public byte[] buffer = new byte[BufferSize];
  // Received data string.
  public StringBuilder sb = new StringBuilder();
}

容器至少为一个socket类型。

===============

 // Read data from the client socket. 

    int bytesRead = handler.EndReceive(ar);

完成一次连接。数据存储在state.buffer里,bytesRead为读取的长度。

handler.BeginSend(byteData, 0, byteData.Length, 0,

      new AsyncCallback(SendCallback), handler);

发送数据byteData,回调函数SendCallback。容器handler

int bytesSent = handler.EndSend(ar);

发送完毕,bytesSent发送字节数。

4 程序结构

主程序:

    byte[] bytes = new Byte[1024];
    IPAddress ipAddress = IPAddress.Parse("192.168.1.104");
    IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

    // 生成一个TCP的socket
    Socket listener = new Socket(AddressFamily.InterNetwork,
      SocketType.Stream, ProtocolType.Tcp);

    listener.Bind(localEndPoint);
    listener.Listen(100);

    while (true)
    {

      // Set the event to nonsignaled state.
      allDone.Reset();

      //开启异步监听socket
      Console.WriteLine("Waiting for a connection");
      listener.BeginAccept(
           new AsyncCallback(AcceptCallback),
           listener);

      // 让程序等待,直到连接任务完成。在AcceptCallback里的适当位置放置allDone.Set()语句.
      allDone.WaitOne();
      }

  Console.WriteLine("\nPress ENTER to continue");
  Console.Read();

连接行为回调函数AcceptCallback:

  public static void AcceptCallback(IAsyncResult ar)

  {

    //添加此命令,让主线程继续.

    allDone.Set();

    // 获取客户请求的socket

    Socket listener = (Socket)ar.AsyncState;

    Socket handler = listener.EndAccept(ar);

    // 造一个容器,并用于接收命令.

    StateObject state = new StateObject();

    state.workSocket = handler;

    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,

      new AsyncCallback(ReadCallback), state);

  }

读取行为的回调函数ReadCallback:

  public static void ReadCallback(IAsyncResult ar)

  {

    String content = String.Empty;

    // 从异步state对象中获取state和socket对象.

    StateObject state = (StateObject)ar.AsyncState;

    Socket handler = state.workSocket;

    // 从客户socket读取数据. 

    int bytesRead = handler.EndReceive(ar);

    if (bytesRead > 0)

    {

      // 如果接收到数据,则存起来

      state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

      // 检查是否有结束标记,如果没有则继续读取

      content = state.sb.ToString();

      if (content.IndexOf("<EOF>") > -1)

      {

        //所有数据读取完毕.

        Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",

          content.Length, content);

        // 给客户端响应.

        Send(handler, content);

      }

      else

      {

        // 接收未完成,继续接收.

        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,

        new AsyncCallback(ReadCallback), state);

      }

    }

  }

发送消息给客户端:

private static void Send(Socket handler, String data)

  {

    // 消息格式转换.

    byte[] byteData = Encoding.ASCII.GetBytes(data);

    // 开始发送数据给远程目标.

    handler.BeginSend(byteData, 0, byteData.Length, 0,

      new AsyncCallback(SendCallback), handler);

  }

private static void SendCallback(IAsyncResult ar)

  {

      // 从state对象获取socket.

      Socket handler = (Socket)ar.AsyncState;

      //完成数据发送

      int bytesSent = handler.EndSend(ar);

      Console.WriteLine("Sent {0} bytes to client.", bytesSent);

      handler.Shutdown(SocketShutdown.Both);

      handler.Close();

  }

在各种行为的回调函数中,所对应的socket都从输入参数的AsyncState属性获得。使用(Socket)或者(StateObject)进行强制转换。BeginReceive函数使用的容器为state,因为它需要存放传送的数据。

而其余接收或发送函数的容器为socket也可。

完整代码

  using System;
  using System.Net;
  using System.Net.Sockets;
  using System.Text;
  using System.Threading;

  // State object for reading client data asynchronously
  public class StateObject
  {
   // Client socket.
   public Socket workSocket = null;
   // Size of receive buffer.
   public const int BufferSize = ;
   // Receive buffer.
   public byte[] buffer = new byte[BufferSize];
   // Received data string.
   public StringBuilder sb = new StringBuilder();
 }

 public class AsynchronousSocketListener
 {
   // Thread signal.
   public static ManualResetEvent allDone = new ManualResetEvent(false);

   public AsynchronousSocketListener()
   {
   }

   public static void StartListening()
   {
     // Data buffer for incoming data.
     byte[] bytes = new Byte[];

     // Establish the local endpoint for the socket.
     // The DNS name of the computer
     // running the listener is "host.contoso.com".
     //IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
     IPAddress ipAddress = IPAddress.Parse("...");

     IPEndPoint localEndPoint = new IPEndPoint(ipAddress, );

     // Create a TCP/IP socket.
     Socket listener = new Socket(AddressFamily.InterNetwork,
       SocketType.Stream, ProtocolType.Tcp);

     // Bind the socket to the local endpoint and listen for incoming connections.
     try
     {
       listener.Bind(localEndPoint);
       listener.Listen();
       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();
       }
     }
     catch (Exception e)
     {
       Console.WriteLine(e.ToString());
     }

     Console.WriteLine("\nPress ENTER to continue");
     Console.Read();
   }

   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, , StateObject.BufferSize, , new AsyncCallback(ReadCallback), state);
   }

   public static void ReadCallback(IAsyncResult ar)
   {
     String content = String.Empty;

     // Retrieve the state object and the handler socket
     // from the asynchronous state object.
     StateObject state = (StateObject)ar.AsyncState;
     Socket handler = state.workSocket;

     // Read data from the client socket.
     int bytesRead = handler.EndReceive(ar);

     if (bytesRead > )
     {
       // There might be more data, so store the data received so far.
       state.sb.Append(Encoding.ASCII.GetString(
         state.buffer, , bytesRead));

       // Check for end-of-file tag. If it is not there, read
       // more data.
       content = state.sb.ToString();
       if (content.IndexOf("<EOF>") > -)
       {
         // All the data has been read from the
         // client. Display it on the console.
         Console.WriteLine("Read {} bytes from socket. \n Data : {}",content.Length, content);

         // Echo the data back to the client.
         Send(handler, content);
       }
       else
       {
         // Not all data received. Get more.
         handler.BeginReceive(state.buffer, , StateObject.BufferSize, , new AsyncCallback(ReadCallback), state);
       }
     }
   }

   private static void Send(Socket handler, String data)
   {
     // Convert the string data to byte data using ASCII encoding.
     byte[] byteData = Encoding.ASCII.GetBytes(data);

     // Begin sending the data to the remote device.
     handler.BeginSend(byteData, , byteData.Length, ,
       new AsyncCallback(SendCallback), handler);
   }

   private static void SendCallback(IAsyncResult ar)

   {
     try
     {
       // Retrieve the socket from the state object.
       Socket handler = (Socket)ar.AsyncState;

       // Complete sending the data to the remote device.
       int bytesSent = handler.EndSend(ar);
       Console.WriteLine("Sent {} bytes to client.", bytesSent);
       handler.Shutdown(SocketShutdown.Both);
       handler.Close();
     }

     catch (Exception e)

     {
       Console.WriteLine(e.ToString());
     }
   }

   public static int Main(String[] args)

   {
     StartListening();
     return ;
   }

 }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索c#
, socket
, 异步
, socket异步通信
实现socket通信
c语言指针详解、c语言题库及详解答案、c语言32个关键字详解、c 编程实例详解、c语言结构体详解,以便于您获取更多的相关知识。

时间: 2024-11-10 07:16:20

详解C# Socket异步通信实例_C#教程的相关文章

详解C# Socket编程笔记_C#教程

看到这个题目,是不是很眼熟?在博客园里搜下,保证会发现关于这个东东的文章实在是太多了~~~真得是没有写得必要,而且我也有点懒得去琢磨字句.(看到这,肯定得来个转折的了,不然就看不到下文了,不是吗)但是,为了自己下一篇要写的文章做参考,还是有必要先补充一下socket基础知识. 注意:如果你已经接触过socket,那就没什么必要耽误时间看下去了.另外,如果发现其中任何错误,欢迎直接指出. 1.按惯例先来介绍下socket Windows中的很多东西都是从Unix领域借鉴过来的,Socket也是一样

详解C# Socket简单例子(服务器与客户端通信)_C#教程

这个例子只是简单实现了如何使用 Socket 类实现面向连接的通信. 注意:此例子的目的只是为了说明用套接字写程序的大概思路,而不是实际项目中的使用程序.在这个例子中,实际上还有很多问题没有解决,如消息边界问题.端口号是否被占用.消息命令的解析问题等.. 下面是两个程序的代码,(两个程序均为控制台程序) 先发服务端的(Server)完整代码如下: 引入命名空间: using System.Net.Sockets; using SystemNet; using SystemThreading; 完

ui-UI 中的tag怎么用 新手求详解,最好是实例+解释 新手初试

问题描述 UI 中的tag怎么用 新手求详解,最好是实例+解释 新手初试 UI 中的tag怎么用 新手求详解,最好是实例+解释 ;;;;;;;;;;;;;;;;;;;;;;;;;;; 解决方案 tag可以附加任何你觉得需要附加的数据.比如说id.额外的字段等等.

详解Linux Socket编程(不限Linux)_Linux

我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠socket?那什么是socket?socket的类型有哪些?还有socket的基本函数,这些都是本文想介绍的.本文的主要内容如下: 1.网络中进程之间如何通信? 本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类: 消息传递(管道.FIFO.消息队列) 同步(互斥量.条件变量.读写锁.文件和

PHP书写格式详解(必看)_php实例

从一个例子开始. 启动编辑器,创建一个php文件并键入如下代码: <?php echo "你好!"; ?> 将该文件命名为 test.php 并存储于 E:html 目录下. 在浏览器地址栏里访问该 php 文件:http://127.0.0.1/test.php,输出结果如下: 你好!在该例子中,我们以 echo 指令输出一个字符串"你好!". 从这个例子可以看出: •PHP 文件或 PHP 代码段以"<?php"开头,以&q

Android AOP 注解详解及简单使用实例(三)

Android  注解 相关文章: Android AOP注解Annotation详解(一) Android AOP之注解处理解释器详解(二) Android AOP 注解详解及简单使用实例(三) 一.简介 在Android 里面 注解主要用来干这么几件事: 和编译器一起给你一些提示警告信息. 配合一些ide 可以更加方便快捷 安全有效的编写Java代码.谷歌出的support-annotations这个库 就是主要干这个的. 和反射一起 提供一些类似于spring 可配置的功能,方便简洁. 二

CentOS 7.2 下编译安装PHP7.0.10+MySQL5.7.14+Nginx1.10.1的方法详解(mini版本)_php实例

一.安装前的准备工作 1.yum update #更新系统 2.yum install gcc gcc-c++ autoconf automake cmake bison m4 libxml2 libxml2-devel libcurl-devel libjpeg-devel libpng-devel libicu-devel #安装php.MySQL.Nngix所依赖的包 3.下载以下包 #我把所有源文件都下载在root目录,读者可自行修改源文件存放目录 3.1 libmcrypt-2.5.8

php魔术常量详解 php魔术常量实例代码

php 魔术常量详解 实例: class MoShu{ public function moshu() { echo '当前类名:' . __CLASS__ . "<br />"; echo '当前方法名:' . __FUNCTION__ . "<br />"; echo '当前文件中所在的行数:' . __LINE__ . "<br />"; echo '当前文件绝对路径:' . __FILE__ . &qu

图文详解Ubuntu下安装配置Mysql教程_Mysql

Ubuntu安装Mysq有l三种安装方式,下面就为大家一一讲解,具体内容如下 1. 从网上安装 sudo apt-get install mysql-server.装完已经自动配置好环境变量,可以直接使用mysql的命令. 注:建议将/etc/apt/source.list中的cn改成us,美国的服务器比中国的快很多. 2. 安装离线包,以mysql-5.0.45-linux-i686-icc-glibc23.tar.gz为例. 3. 二进制包安装:安装完成已经自动配置好环境变量,可以直接使用m