本文转载自:http://www.cnblogs.com/llllll/archive/2009/05/13/1455703.html

服务器端

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("") > -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 = 1024;
    // 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[1024];         // 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("192.168.1.104");
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);         // 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(100);             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, 0, StateObject.BufferSize, 0,
            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 > 0)
        {
            // There  might be more data, so store the data received so far.
            state.sb.Append(Encoding.ASCII.GetString(
                state.buffer, 0, bytesRead));             // Check for end-of-file tag. If it is not there, read 
            // more data.
            content = state.sb.ToString();
            if (content.IndexOf("") > -1)
            {
                // All the data has been read from the 
                // client. Display it on the console.
                Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
                    content.Length, content);
                // Echo the data back to the client.
                Send(handler, content);
            }
            else
            {
                // Not all data received. Get more.
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                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, 0, byteData.Length, 0,
            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 {0} 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 0;
    }
}

(转)C# Socket异步通信的更多相关文章

  1. socket异步通信-如何设置成非阻塞模式、非阻塞模式下判断connect成功(失败)、判断recv/recvfrom成功(失败)、判断send/sendto

    socket异步通信-如何设置成非阻塞模式.非阻塞模式下判断connect成功(失败).判断recv/recvfrom成功(失败).判断send/sendto 博客分类: Linux Socket s ...

  2. Socket异步通信学习三

    接下来是客户端部分,采用同步接收模式,在SocketClient项目中新建了一个SynServer类,用于存放socket服务器代码,和AsynServer类似,主要有4个方法: 有一个全局socke ...

  3. Socket异步通信学习二

    接下来是服务器部分,采用异步模式,新建了一个AsynServer类,用于存放socket服务器代码,主要有4个方法: 有一个全局socket,下面四个方法中都用到. Socket socket = n ...

  4. Socket异步通信学习一

    最近在做一个频谱管理项目,负责通信模块,自己也是小白,重头学起,直至今天通信基本框架已经完成,把自己在学习中的心得与大家分享一下,做一个socket系列的博文,顺便加固一下自己对socket通信的认识 ...

  5. Socket异步通信及心跳包同时响应逻辑分析。

    有段时间没有更博了,刚好最近在做Socket通信的项目,原理大致内容:[二维码-(加logo)]-->提供主机地址和端口号信息(直接使用[ThoughtWorks.QRCode.dll]比较简单 ...

  6. socket 异步通信的一些问题

    socket通信在使用时被封装很简单,像操作文件一样简单,正是因为简单里面好多细节需要深入研究一下. windows下通信有select和iocp方式,select是传统方式,在socket里使用re ...

  7. Socket 异步通信

    最近在写数据通信的时候用到的东西!希望对大家有帮助 /// <summary> /// 获取或设置服务器IP地址 /// </summary> public string se ...

  8. Socket异步通信及心跳包同时响应逻辑分析(最后附Demo)。

    有段时间没有更博了,刚好最近在做Socket通信的项目,原理大致内容:[二维码-(加logo)]-->提供主机地址和端口号信息(直接使用[ThoughtWorks.QRCode.dll]比较简单 ...

  9. Socket 异步通信示例

    这个项目是一个控制台应用程序: 服务器端: using System; using System.Net; using System.Net.Sockets; using System.Text; u ...

随机推荐

  1. 一次穿墙渗透测试,利用IPC跨域

    Shell是怎么拿下的我们就不纠结了. 我们来上传菜刀一句话,来仔细分析分析. 先来看看内网环境把. 很高兴的是现在管理员在线.可以抓去文明密码. 但是很悲催的又是.服务器不支持走TCP协议.HTTP ...

  2. NQueens, NQueens2 N皇后问题,递归回溯

    N皇后的规则:任意两个皇后不在同一行,不在同一列,不在同一斜线上. 算法分析:这种问题就用回溯法.深度搜索然后回溯.用一个数组记录每一行皇后的位置,下标代表行,值代表列.对行深度搜索. public ...

  3. MapReduce job在JobTracker初始化源码级分析

    mapreduce job提交流程源码级分析(三)中已经说明用户最终调用JobTracker.submitJob方法来向JobTracker提交作业.而这个方法的核心提交方法是JobTracker.a ...

  4. Linux 实用指令之查看端口开启情况

    netstat -ntlp 查看端口使用情况! netstat -ntlp | grep 80 查看具体的端口是否使用! # netstat -ntlp Active Internet connect ...

  5. scala学习手记3 - var和val

    scala中用var和val定义变量都是可以的. 用val定义的变量是不可变的,被初始化后值就固定下来,不可以再被修改(这类似于java中的final关键字):用var定义的变量是可变的,可以任意修改 ...

  6. django中Model表的反向查询

    很多时候需要在多张表之间进行跨表查询,这其中外键是必须存在的,而通过外键所处的表的对象进行跨表查询, 称为正向查询.反之,则是反向查询. 正向查询很简单,这里不谈. 主要谈下反向查询. class U ...

  7. mysql数据库优化课程---6、mysql结构化查询语言有哪些

    mysql数据库优化课程---6.mysql结构化查询语言有哪些 一.总结 一句话总结:主要分为四类 1.DCL 数据控制语言1)grant2)commit3)rollback 2.DDL 数据定义语 ...

  8. 5.6 WebDriver API实例讲解(41-50)

    41.操作Web页面的滚动条 (1)滑动页面的滚动条到页面的最下面. (2)滑动页面的滚动条到页面的某个元素. (3)滑动页面的滚动条向下移动某个数量的像素. package apiSample; i ...

  9. 十一 web爬虫讲解2—Scrapy框架爬虫—Scrapy使用

    xpath表达式 //x 表示向下查找n层指定标签,如://div 表示查找所有div标签 /x 表示向下查找一层指定的标签 /@x 表示查找指定属性的值,可以连缀如:@id @src [@属性名称= ...

  10. C++纯虚函数和抽象类的一些要点

    1. 纯虚函数是在其被声明的类中不被实现的函数. 2. 定义了纯虚函数的类是抽象类,可以用来生命变量,但不能用来构造实例. 3. 基类中定义了纯虚函数,派生类要么定义这个纯虚函数,要么重复声明一次这个 ...