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