C#:简单的Socket异步通信服务

本文介绍了一种基于异步Socket的服务端实现方案,包括接收客户端消息、定时向客户端发送消息及处理客户端请求等功能。通过使用面向连接的TCP协议,确保了通信的稳定性和实时性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Socket

请参考此链接来获取对于Socket的认识:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.aspx

目标

1、服务端接收到来自客户端的消息

2、服务端间歇性地向客户端发送消息

3、服务端主动向客户端发送消息

思路

通过对Socket的学习后,可以知道:

1、Socket分为面向连接协议(如TCP)和无连接协议(如UDP)

2、Socket通信分为同步操作模式和异步操作模式,同步模式在建立连接之前/收到消息之前会阻塞当前进程,异步模式不会阻塞当前进程

综合以上两点,考虑到体验,当然是选择异步Socket啦,另外,这里使用的是面向连接的协议,那么实现思路大致如下:

1、创建Socket对象

2、绑定IP和端口

3、侦听连接

4、开始一个异步操作来接收一个接入的连接请求

5、处理接入的请求

6、向客户端发送消息

代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.IO;
using Microsoft.Win32;
using System.Threading;
using System.Net;
using System.Net.Sockets;


namespace TSNotifier
{
    public partial class TSNotifier : ServiceBase
    {
        Socket socket;
        public TSNotifier()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 服务启动
        /// </summary>
        /// <param name="args"></param>
        protected override void OnStart(string[] args)
        {
            //Debugger.Launch();//启动调试,生产环境删掉
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Bind(new IPEndPoint(IPAddress.Any, 4530));//侦听来自任意IP的连接请求
            socket.Listen(500);
            socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
        }
        /// <summary>
        /// 服务停止
        /// </summary>
        protected override void OnStop()
        {
            try
            {
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
            }
            catch (Exception ex)
            {


            }
        }


        public static void ClientAccepted(IAsyncResult ar)
        {
            var socket = ar.AsyncState as Socket;
            var client = socket.EndAccept(ar);
            string clientIp = ((System.Net.IPEndPoint)client.RemoteEndPoint).Address.ToString();
            string clientPort = ((System.Net.IPEndPoint)client.RemoteEndPoint).Port.ToString();
            client.Send(Encoding.Unicode.GetBytes("Hi " + clientIp + ":" + clientPort + ", I accept you request at " + DateTime.Now.ToString()));


            //每隔两秒钟给客户端发一个消息
            var timer = new System.Timers.Timer();
            timer.Interval = 2000;
            timer.Enabled = true;
            timer.Elapsed += (o, a) =>
            {
                //检测客户端Socket的状态
                if (client.Connected)
                {
                    try
                    {
                        client.Send(Encoding.Unicode.GetBytes("Server online."));
                    }
                    catch (SocketException ex)
                    {


                    }
                }
                else
                {
                    timer.Stop();
                    timer.Enabled = false;
                }
            };
            timer.Start();
            //接收客户端的消息
            try
            {
                client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client);
            }
            catch (Exception ex)
            {


            }
            //准备接受下一个客户端请求
            socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
        }


        static byte[] buffer = new byte[1024];
        public static void ReceiveMessage(IAsyncResult ar)
        {
            var socket = ar.AsyncState as Socket;
            string clientIp = ((IPEndPoint)socket.RemoteEndPoint).Address.ToString();
            string clientPort = ((IPEndPoint)socket.RemoteEndPoint).Port.ToString();
            try
            {
                var length = socket.EndReceive(ar);
                var message = Encoding.Unicode.GetString(buffer, 0, length);
                socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
            }
            catch (Exception ex)
            {


            }
        }
    }
}

客户端的实现请参考:http://www.rexcao.net/archives/161


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值