新思想

C# 同步/异步即时通信/聊天 源代码

一、同步聊天

服务器端:

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

public class SynchronousSocketServer
{

    // 接收到的客户端的消息.
    public static string data = null;

    public static void StartListening()
    {
        // 接收缓冲.
        byte[] bytes;

        // 通过DNS获得本地的 Endpoint
        //IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
        //IPAddress ipAddress = ipHostInfo.AddressList[0];
        //IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
        IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Loopback, 11000);

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

        // 绑定 socket 的本地地址
        // 监听连接申请.
        try
        {
            listener.Bind(localEndPoint);
            listener.Listen(10);

            // 监听连接申请.
            while (true)
            {
                Console.WriteLine("等待连接 ...");
                // 程序被阻塞,等待用户连接
                Socket handler = listener.Accept();
                data = null;

                // 处理用户的连接.
                while (true)
                {
                    bytes = new byte[1024];
                    int bytesRec = handler.Receive(bytes);
                    data = Encoding.Default.GetString(bytes, 0, bytesRec);
                    Console.WriteLine("{0}: {1}", handler.RemoteEndPoint, data);
                    if (data.ToUpper() == "EXIT")
                        break;
                }

                //// Show the data on the console.
                //Console.WriteLine("Text received : {0}", data);

                // Echo the data back to the client.
                byte[] msg = Encoding.Default.GetBytes("连接已断开.");

                handler.Send(msg);
                handler.Shutdown(SocketShutdown.Both);
                handler.Close();
            }

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

        Console.WriteLine("\n按 ENTER 键继续 ...");
        Console.Read();
    }

    public static int Main(String[] args)
    {
        StartListening();
        return 0;
    }
}

 

客户端:

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

public class SynchronousSocketClient
{

    public static void StartClient()
    {
        // 接收缓冲.
        byte[] bytes = new byte[1024];
        string str = null;

        // 链接到远程服务器.
        try
        {
            // 建立远程 Endpoint .
            //IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(args[0]), 11000);
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000);

            // 建立 TCP/IP socket.
            Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            // 连接到 remote endpoint
            try
            {
                sender.Connect(remoteEP);

                Console.WriteLine("已连接到 {0}\n请输入聊天信息: ",
                    sender.RemoteEndPoint.ToString());

                while (true)
                {
                    str = Console.ReadLine();

                    // 编码.
                    byte[] msg = Encoding.Default.GetBytes(str);

                    // 发送消息.
                    int bytesSent = sender.Send(msg);

                    if (str.ToUpper() == "EXIT")
                        break;
                }

                // 接收响应.
                int bytesRec = sender.Receive(bytes);
                Console.WriteLine("接收到: {0}",
                    Encoding.Default.GetString(bytes, 0, bytesRec));

                // 关闭 socket.
                sender.Shutdown(SocketShutdown.Both);
                sender.Close();

                Console.ReadKey();
            }
            catch (ArgumentNullException ane)
            {
                Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
            }
            catch (SocketException se)
            {
                Console.WriteLine("SocketException : {0}", se.ToString());
            }
            catch (Exception e)
            {
                Console.WriteLine("Unexpected exception : {0}", e.ToString());
            }

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

    public static int Main(String[] args)
    {
        StartClient();
        return 0;
    }
}

 

二、异步聊天

服务器端:

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

// StateObject 用于保存异步读取的客户端数据
public class StateObject
{
    // 客户端 socket.
    public Socket workSocket = null;
    // 接收缓冲的大小.
    public const int BufferSize = 1024;
    // 接收缓冲.
    public byte[] buffer = new byte[BufferSize];
    // 接收到的消息.
    public StringBuilder sb = new StringBuilder();
}

public class AsynchronousSocketListener
{
    // 线程信号.
    public static ManualResetEvent allDone = new ManualResetEvent(false);

    public AsynchronousSocketListener()
    {
    }

    public static void StartListening()
    {
        // 输入缓冲.
        byte[] bytes = new Byte[1024];

        // 建立本地 Endpoint .
        //IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
        //IPAddress ipAddress = ipHostInfo.AddressList[0];
        //IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
        IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Loopback, 11000);

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

        // 绑定本地 endpoint 并 监听进入的连接.
        try
        {
            listener.Bind(localEndPoint);
            listener.Listen(100);

            while (true)
            {
                // 重置事件的 无信号 状态.
                allDone.Reset();

                // 启动异步 socket 来监听连接.
                Console.WriteLine("等待连接 ...");
                listener.BeginAccept(
                    new AsyncCallback(AcceptCallback),
                    listener);

                // 等待,只到连接被建立.
                allDone.WaitOne();
            }

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

        Console.WriteLine("\n按 ENTER 键继续 ...");
        Console.Read();
    }

    public static void AcceptCallback(IAsyncResult ar)
    {
        // 发信号让主线程继续.
        allDone.Set();

        // 获取客户连接.
        Socket listener = (Socket)ar.AsyncState;
        Socket handler = listener.EndAccept(ar);

        // 建立 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;

        // 恢复 state object 和 socket.
        StateObject state = (StateObject)ar.AsyncState;
        Socket handler = state.workSocket;

        // 从客户 socket 读取消息. 
        int bytesRead = handler.EndReceive(ar);

        if (bytesRead > 0)
        {
            // 存储收到的消息.
            state.sb.Append(Encoding.Default.GetString(
                state.buffer, 0, bytesRead));

            // 检查结束标记.
            content = state.sb.ToString();
            if (content.IndexOf("<EOF>") > -1)
            {
                // 显示获得的客户端的所有信息.
                Console.WriteLine("从 {0} 获得了 {1} 个字符: {2}",
                    state.workSocket.RemoteEndPoint, 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.Default.GetBytes(data);

        // 送数据到客户端.
        handler.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallback), handler);
    }

    private static void SendCallback(IAsyncResult ar)
    {
        try
        {
            // 从 state object 恢复 Socket.
            Socket handler = (Socket)ar.AsyncState;

            // 发送数据.
            int bytesSent = handler.EndSend(ar);
            Console.WriteLine("发送 {0} 个字符给 {1}.", bytesSent, handler.RemoteEndPoint);

            handler.Shutdown(SocketShutdown.Both);
            handler.Close();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }


    public static int Main(String[] args)
    {
        StartListening();
        return 0;
    }
}

 

客户端:

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

// State object 保存从远程端收到的消息.
public class StateObject
{
    // 客户 socket.
    public Socket workSocket = null;
    // 接收缓冲的大小.
    public const int BufferSize = 256;
    // 接收缓冲.
    public byte[] buffer = new byte[BufferSize];
    // 收到的消息.
    public StringBuilder sb = new StringBuilder();
}

public class AsynchronousClient
{
    // 远程端口号.
    private const int port = 11000;

    // 手工结束事件的信号.
    private static ManualResetEvent connectDone =
        new ManualResetEvent(false);
    private static ManualResetEvent sendDone =
        new ManualResetEvent(false);
    private static ManualResetEvent receiveDone =
        new ManualResetEvent(false);

    // 远程设备的响应.
    private static String response = String.Empty;

    private static void StartClient()
    {
        // 建立连接.
        try
        {
            // 建立连接的远端 endpoint .
            IPHostEntry ipHostInfo = Dns.GetHostEntry("127.0.0.1");
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);

            // 建立 TCP/IP socket.
            Socket client = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);

            // 连接到远端 endpoint .
            client.BeginConnect(remoteEP,
                new AsyncCallback(ConnectCallback), client);
            connectDone.WaitOne();

            // 送测试数据到远端.
            Send(client, "测试数据 <EOF>");
            sendDone.WaitOne();

            // 接收远端发回的消息.
            Receive(client);
            receiveDone.WaitOne();

            // 输出远端发回的消息.
            Console.WriteLine("收到的响应 : {0}", response);

            // 释放 socket.
            client.Shutdown(SocketShutdown.Both);
            client.Close();

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

    private static void ConnectCallback(IAsyncResult ar)
    {
        try
        {
            // 从 state object 中恢复 socket .
            Socket client = (Socket)ar.AsyncState;

            // 完成连接.
            client.EndConnect(ar);

            Console.WriteLine("Socket 连接到 {0}",
                client.RemoteEndPoint.ToString());

            // 发链接已建立的信号.
            connectDone.Set();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private static void Receive(Socket client)
    {
        try
        {
            // 建立 state object.
            StateObject state = new StateObject();
            state.workSocket = client;

            // 开始从远端接收消息.
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReceiveCallback), state);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private static void ReceiveCallback(IAsyncResult ar)
    {
        try
        {
            // 恢复 state object 和远程 socket 
            StateObject state = (StateObject)ar.AsyncState;
            Socket client = state.workSocket;

            // 从远端接收消息.
            int bytesRead = client.EndReceive(ar);

            if (bytesRead > 0)
            {
                // 读取数据.
                state.sb.Append(Encoding.Default.GetString(state.buffer, 0, bytesRead));

                // 继续读剩下的数据.
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
            }
            else
            {
                // 当数据全部到达后; 发回响应.
                if (state.sb.Length > 1)
                {
                    response = state.sb.ToString();
                }
                // 发出收到所有消息的信号.
                receiveDone.Set();
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private static void Send(Socket client, String data)
    {
        // 编码字符串.
        byte[] byteData = Encoding.Default.GetBytes(data);

        // 开始送数据到客户端.
        client.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallback), client);
    }

    private static void SendCallback(IAsyncResult ar)
    {
        try
        {
            // 从 state object 中恢复 socket .
            Socket client = (Socket)ar.AsyncState;

            // 完成数据的发送.
            int bytesSent = client.EndSend(ar);
            Console.WriteLine("送 {0} 个字符到服务器.", bytesSent);

            // 发数据已发送的信号.
            sendDone.Set();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    public static int Main(String[] args)
    {
        StartClient();
        return 0;
    }
}

 

源程序下载

执行程序下载

posted on 2015-12-16 09:21  新思想  阅读(776)  评论(0)    收藏  举报

导航