稳扎稳打Silverlight(24) - 2.0通信之Socket, 开发一个多人聊天室

[索引页]
[源码下载]


稳扎稳打Silverlight(24) - 2.0通信之Socket, 开发一个多人聊天室


作者:webabcd


介绍
Silverlight 2.0 Socket通信。开发一个多人聊天室
    服务端:实例化Socket, 绑定, 监听, 连接, 接收数据, 发送数据
    客户端:实例化Socket, 指定服务端地址, 连接, 接收数据, 发送数据


在线DEMO
http://webabcd.blog.51cto.com/1787395/342779

示例
1、Policy服务(向客户端发送策略文件的服务)
clientaccesspolicy.xml
<? xml version ="1.0" encoding ="utf-8" ?>
< access-policy >
         < cross-domain-access >
                 < policy >
                         < allow-from >
                                 < domain uri ="*" />
                         </ allow-from >
                         < grant-to >
                                 < socket-resource port ="4502-4534" protocol ="tcp" />
                         </ grant-to >
                 </ policy >
         </ cross-domain-access >
</ access-policy >
 
Main.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Net.Sockets;
using System.IO;
using System.Net;

namespace PolicyServer
{
         public partial class Main : Form
        {
                 // 客户端 socket 发送到服务端的对策略文件的请求信息
                 private readonly string _policyRequestString = "<policy-file-request/>";

                 private Socket _listener; // 服务端监听的 socket
                 private byte[] _policyBuffer; // 服务端策略文件的 buffer
                 private byte[] _requestBuffer; // 客户端 socket 发送的请求信息的 buffer

                 private int _received; // 接收到的信息字节数

                 private bool _flag = false; // 标志位。服务端是否要处理传入的连接

                System.Threading.SynchronizationContext _syncContext;

                 public Main()
                {
                        InitializeComponent();

                        _flag = true;

                        lblStatus.Text = "PolicyServer状态:启动";
                        lblStatus.ForeColor = Color.Green;

                         // 启动 PolicyServer
                        StartupPolicyServer();

                         // UI 线程
                        _syncContext = System.Threading.SynchronizationContext.Current;
                }

                 private void btnStartup_Click( object sender, EventArgs e)
                {
                        _flag = true;

                        lblStatus.Text = "PolicyServer状态:启动";
                        lblStatus.ForeColor = Color.Green;
                }

                 private void btnPause_Click( object sender, EventArgs e)
                {
                        _flag = false;

                        lblStatus.Text = "PolicyServer状态:暂停";
                        lblStatus.ForeColor = Color.Red;
                }

                 /// <summary>
                 /// 启动 PolicyServer
                 /// </summary>
                 private void StartupPolicyServer()
                {
                         string policyFile = Path.Combine(Application.StartupPath, "clientaccesspolicy.xml");

                         using (FileStream fs = new FileStream(policyFile, FileMode.Open, FileAccess.Read))
                        {
                                 // 将策略文件的内容写入 buffer
                                _policyBuffer = new byte[fs.Length];
                                fs.Read(_policyBuffer, 0, _policyBuffer.Length);
                        }

                         // 初始化 socket , 然后与端口绑定, 然后对端口进行监听
                        _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        _listener.Bind( new IPEndPoint(IPAddress.Any, 943)); // socket 请求策略文件使用 943 端口
                        _listener.Listen(100);

                         // 开始接受客户端传入的连接
                        _listener.BeginAccept( new AsyncCallback(OnClientConnect), null);
                }

                 private void OnClientConnect(IAsyncResult result)
                {
                         if (!_flag)
                        {
                                 // PolicyServer 停用的话,则不再处理传入的连接
                                _listener.BeginAccept( new AsyncCallback(OnClientConnect), null);
                                 return;
                        }
                                    
                        Socket client; // 客户端发过来的 socket

                         try
                        {
                                 // 完成接受客户端传入的连接的这个异步操作,并返回客户端连入的 socket
                                client = _listener.EndAccept(result);
                        }
                         catch (SocketException)
                        {
                                 return;
                        }

                        _requestBuffer = new byte[_policyRequestString.Length];
                        _received = 0;

                         try
                        {
                                 // 开始接收客户端传入的数据
                                client.BeginReceive(_requestBuffer, 0, _policyRequestString.Length, SocketFlags.None, new AsyncCallback(OnReceive), client);
                        }
                         catch (SocketException)
                        {
                                 // socket 出错则关闭客户端 socket
                                client.Close();
                        }

                         // 继续开始接受客户端传入的连接
                        _listener.BeginAccept( new AsyncCallback(OnClientConnect), null);
                }


                 private void OnReceive(IAsyncResult result)
                {
                        Socket client = result.AsyncState as Socket;

                         try
                        {
                                 // 完成接收数据的这个异步操作,并计算累计接收的数据的字节数
                                _received += client.EndReceive(result);

                                 if (_received < _policyRequestString.Length)
                                {
                                         // 没有接收到完整的数据,则继续开始接收
                                        client.BeginReceive(_requestBuffer, _received, _policyRequestString.Length - _received, SocketFlags.None, new AsyncCallback(OnReceive), client);
                                         return;
                                }

                                 // 把接收到的数据转换为字符串
                                 string request = System.Text.Encoding.UTF8.GetString(_requestBuffer, 0, _received);

                                 if (StringComparer.InvariantCultureIgnoreCase.Compare(request, _policyRequestString) != 0)
                                {
                                         // 如果接收到的数据不是“<policy-file-request/>”,则关闭客户端 socket
                                        client.Close();
                                         return;
                                }

                                 // 开始向客户端发送策略文件的内容
                                client.BeginSend(_policyBuffer, 0, _policyBuffer.Length, SocketFlags.None, new AsyncCallback(OnSend), client);
                        }

                         catch (SocketException)
                        {
                                 // socket 出错则关闭客户端 socket
                                client.Close();
                        }
                }

                 private void OnSend(IAsyncResult result)
                {
                        Socket client = result.AsyncState as Socket;

                         try
                        {
                                 // 完成将信息发送到客户端的这个异步操作
                                client.EndSend(result);

                                 // 获取客户端的ip地址及端口号,并显示
                                _syncContext.Post(ResultCallback, client.LocalEndPoint.ToString());
                        }
                         finally
                        {
                                 // 关闭客户端 socket
                                client.Close();
                        }
                }

                 void ResultCallback( object result)
                {
                         // 输出客户端的ip地址及端口号
                        txtMsg.Text += result.ToString() + "\r\n";
                }
        }
}
 
 
2、Socket服务端(聊天室的服务端)
ClientSocketPacket.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SocketServer
{
         /// <summary>
         /// 对客户端 Socket 及其他相关信息做一个封装
         /// </summary>
         public class ClientSocketPacket
        {
                 /// <summary>
                 /// 客户端 Socket
                 /// </summary>
                 public System.Net.Sockets.Socket Socket { get; set; }

                 private byte[] _buffer;
                 /// <summary>
                 /// 为该客户端 Socket 开辟的缓冲区
                 /// </summary>
                 public byte[] Buffer
                {
                        get
                        {
                                 if (_buffer == null)
                                        _buffer = new byte[32];

                                 return _buffer;
                        }
                }

                 private List< byte> _receivedByte;
                 /// <summary>
                 /// 客户端 Socket 发过来的信息的字节集合
                 /// </summary>
                 public List< byte> ReceivedByte
                {
                        get
                        {
                                 if (_receivedByte == null)
                                        _receivedByte = new List< byte>();

                                 return _receivedByte;
                        }
                }
        }
}
 
 未完待续>>
 
 
OK
[源码下载]
 

你可能感兴趣的:(socket,通信,silverlight,聊天室,稳扎稳打)