惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
V
Vulnerabilities – Threatpost
Google Online Security Blog
Google Online Security Blog
Hugging Face - Blog
Hugging Face - Blog
L
LINUX DO - 热门话题
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
D
Docker
C
Cyber Attacks, Cyber Crime and Cyber Security
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
T
Tenable Blog
P
Privacy International News Feed
Google DeepMind News
Google DeepMind News
小众软件
小众软件
Cisco Talos Blog
Cisco Talos Blog
aimingoo的专栏
aimingoo的专栏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
A
Arctic Wolf
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cisco Blogs
T
Threat Research - Cisco Blogs
NISL@THU
NISL@THU
The Hacker News
The Hacker News
Project Zero
Project Zero
AWS News Blog
AWS News Blog
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threatpost
V
Visual Studio Blog
The GitHub Blog
The GitHub Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
Jina AI
Jina AI
Cyberwarzone
Cyberwarzone
The Register - Security
The Register - Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
Vercel News
Vercel News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
MongoDB | Blog
MongoDB | Blog
U
Unit 42
Scott Helme
Scott Helme
A
About on SuperTechFans
WordPress大学
WordPress大学
F
Fortinet All Blogs
大猫的无限游戏
大猫的无限游戏
G
GRAHAM CLULEY
Latest news
Latest news
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
Schneier on Security

博客园 - henry

Smark.Net.Tcp.XmlService性能测试程序 基于Flex的http简易文件管理工具 性能的瓶颈到底在那呢? 运用Smark.SocketAsyncs扩展基于XML的TCP服务 实现分布式对象锁 发布一个C#实现的Asterisk的管理系统 asterisk使用SIP相互对接 开源一个基于Flex4+C#的个人信息管理程序 FlashBuilder4试用 这样的重构是否有必要呢? Asterisk2B用户管理逻辑设计 用JQuery UI dialog实现Alert和Confirm功能 - henry Asterisk发起电话预约回拔 WOW工会DKP管理系统 我的分页控件设计 实现一个JavaScript验证的Asp.net Helper - henry - 博客园 Smark.Data 实体属性值描述 Smark.Data实体成员数据验证 Smark.Data Part1
运用Smark.SocketAsyncs方便实现数据交互服务
henry · 2010-06-23 · via 博客园 - henry

 Smark.SocketAsyncs是通过SocketAsyncEventArgs对Socket进行包装的处理程序,暂时只封装了对Tcp的支持。以下是通过Smark.SocketAsyncs封装一个简单的数据交互服务。
1)制定基础数据传输描述
 实现消息转换适配器

代码


    
public class MessageAdapter:Smark.SocketAsyncs.IMessage
    {
        
public object Message
        {
            
get;
            
set;
        }
        
#region IMessage 成员
        
public void SaveData(Encoding coding, Smark.SocketAsyncs.SendBuffer buffer)
        {
            buffer.Write(Smark.Core.Functions.SerializeObject(Message));
            buffer.WriteRN();
        }
        
public void LoadData(Encoding coding, Smark.SocketAsyncs.ReceiveBuffer buffer)
        {
            
byte[] data = buffer.ToBytes();
            Message 
= Smark.Core.Functions.DeserializeObject(data);
        }
        
#endregion
    }

 适配器主要功能是对象和byte之前的转换.

 实现命令和返回类型描述

代码

    [Serializable]
    
public class Command
    {
        
        
public CommandType Type
        {
            
get;
            
set;
        }
        
private List<object> mParameters = new List<object>();
        
public List<object> Parameters
        {
            
get
            {
                
return mParameters;
            }
        }
        
public object this[int index]
        {
            
get
            {
                
return Parameters[index];
            }
        }
        
    }
    
public enum CommandType
    {
        ListEmployee,
        LoadEmployee
    }
    [Serializable]
    
public class Result
    {
        
public object Data { getset; }
        
public string ErrorMessage { getset; }
    }

2)服务端代码实现
 建立一个控制台程序,定义相关监听对象和启用服务

代码

            Functions.LogOutputToConsole = LogType.Track;
            
string dbstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=";
            dbstring 
+= Smark.Core.Functions.GetPath(typeof(Program).Assembly);
            dbstring 
+= "Northwind.mdb";
            DBContext.SetConnectionString(ConnectionType.Context1, dbstring);
            TcpServer
<TcpClient<EofAtEnter>> server = new TcpServer<TcpClient<EofAtEnter>>();
            server.ClientConnected 
+= (o, e) => {
                Functions.WriteLog(LogType.Track, 
typeof(Program), "{0} On Connected \t {1}", e.Client.Name,DateTime.Now);
            };
            server.ClientDisposed 
+= (o, e) => {
                Functions.WriteLog(LogType.Track, 
typeof(Program), "{0} On Disposed \t {1}", e.Client.Name,DateTime.Now);
            };
            server.ClientError 
+= (o, e) => {
                Functions.WriteLog(LogType.Track, 
typeof(Program), "{0} On Error:{1} \t {2}", e.Client.Name,e.Exception.Message, DateTime.Now);
            };
            server.ClientReceive 
+= (o, e) => {
                
try
                {
                   
                    Modules.Command cmd 
= (Modules.Command)Functions.DeserializeObject(e.Buffer.Data, e.Buffer.Count - 2);
                    Execute(cmd,e.Client);
                }
                
catch (Exception e_)
                {
                    Functions.WriteLog(LogType.Track, 
typeof(Program), "{0} Data Error:{1} \t {2}", e.Client.Name, e_.Message, DateTime.Now);
                    e.Client.Dispose();
                }
            };
            server.Open(Functions.AppSettingValue(
"ip"),Functions.AppSettingValue<int>("port"),100);
            Functions.WriteLog(LogType.Track, 
typeof(Program), "SocketAsyncsForNorthwind.ServerApp Start \t {0}",DateTime.Now);
            Console.Read();

 以上是构建一个Tcp服务,并以/r/n作为结束分析协议。

 命令分发和处理代码

代码

        static void Execute(Modules.Command cmd,ITcpClient client)
        {
            StringBuilder sb 
= new StringBuilder();
            sb.AppendLine(
"Execute Command:" + cmd.Type);
            
foreach(object item in cmd.Parameters)
            {
                sb.AppendFormat(
"Parameter:{0}\r\n", item);

            }
            
            Functions.WriteLog(LogType.Track, 

typeof(Program), sb.ToString());
            
switch (cmd.Type)
            {
                
case SocketAsyncsForNorthwind.Modules.CommandType.LoadEmployee:
                    LoadEmployee(cmd,client);
                    
break;
                
case SocketAsyncsForNorthwind.Modules.CommandType.ListEmployee:
                    ListEmployee(cmd, client);
                    
break;

            }
        }

static void ListEmployee(Modules.Command cmd, ITcpClient client)
        {
            Modules.Result resul 
= new SocketAsyncsForNorthwind.Modules.Result();
            
try
            {
                Expression exp 
= new Expression();
                
if (cmd.Parameters[0!= null)
                    exp 
&= Modules.Employees.firstName.Match(cmd[0]);
                
if (cmd[1!= null)
                    exp 
&= Modules.Employees.lastName.Match(cmd[0]);
                
if (cmd[2!= null)
                    exp 
&= Modules.Employees.region.Match(cmd[0]);
                resul.Data 
= exp.List<Modules.Employees>();
            }
            
catch (Exception e_)
            {
                resul.ErrorMessage 
= e_.Message;
            }
            SendData(resul, client);
        }
         
        
static void LoadEmployee(Modules.Command cmd,ITcpClient client)
        {
            Modules.Result resul 
= new SocketAsyncsForNorthwind.Modules.Result();
            
try
            {
                Modules.Employees employee 
= DBContext.Load<Modules.Employees>(cmd.Parameters[0]);
                resul.Data 
= employee;
            }
            
catch (Exception e_)
            {
                resul.ErrorMessage 
= e_.Message;
            }
            SendData(resul, client);
           

        }

static void SendData(object data, ITcpClient client)
        {
            Modules.MessageAdapter ma 
= new SocketAsyncsForNorthwind.Modules.MessageAdapter();
            ma.Message 
= data;
            client.Send(ma);
        }


3)客户端实调用处理
 客户端逻辑包装类
 由于Smark.SocketAsyncs是基于异步处理的,所以为了方便调用封装一个基本同步发送和接放的包装类。

代码

public class NorthWindClient:IDisposable
    {
private System.Threading.EventWaitHandle mHandler = new System.Threading.EventWaitHandle(false, System.Threading.EventResetMode.ManualReset);
        
private TcpClient<EofAtEnter> mClient;
        
public NorthWindClient(string ip, int port)
        {
            Init(ip, port);
        }
        
private void Init(string ip,int port)
        {
            mClient 
= TcpServer<TcpClient<EofAtEnter>>.CreateClient(ip, port);
            mClient.Receive();
            mClient.Error 
+= (o, e) => {
                Result 
= new Result();
                Result.ErrorMessage 
= e.Exception.Message;
                mHandler.Set();
            };
            mClient.DataReceive 
+= (o, e) => {
                
byte[] data = e.Buffer.ToBytes(0, e.Buffer.Count - 2);
                Result 
= (Modules.Result)Functions.DeserializeObject(data);
                mHandler.Set();
            };
        }
        
public Result Result
        {
            
get;
            
set;
        }
        
public IList<Employees> ListEmployees(string firstname, string lastname, string region)
        {
            Result 
= null;
            Modules.Command cmd 
= new Command();
            cmd.Type 
= CommandType.ListEmployee;
            cmd.Parameters.Add(firstname);
            cmd.Parameters.Add(lastname);
            cmd.Parameters.Add(region);
            
return (IList<Employees>)SendData(cmd);
        }
        
public Employees LoadEmployee(int id)
        {
            Result 
= null;
            Modules.Command cmd 
= new Command();
            cmd.Type 
= CommandType.LoadEmployee;
            cmd.Parameters.Add(id);
           
return (Employees) SendData(cmd);
           
           

        }

protected object SendData(object data)
        {
            
return SendData(data, 2000);
        }
        
protected object SendData(object data,int timeout)
        {
            Modules.MessageAdapter ma 
= new MessageAdapter();
            ma.Message 
= data;
            mClient.Send(ma);
            mHandler.Reset();
            mHandler.WaitOne(timeout);
            
if (Result == null)
            {
                
throw new Exception("超时!");
            }
            
else if (Result.ErrorMessage != null)
            {
                
throw new Exception(Result.ErrorMessage);
            }
            
return Result.Data;
        }
        
#region IDisposable 成员public void Dispose()
        {
            
if (mClient != null)
                mClient.Dispose();
        }
#endregion
    }

 NorthWindClient功能在初始化的时候接入的服务器,每个逻辑在请求时挂起2秒等待处理,处理错误或超时返回异常。当接收到服务端处理完后取消挂起返回处理值。

 客户端UI处理代码

代码

    public partial class Form1 : Form
    {
        
private Modules.NorthWindClient Client;
        
public Form1()
        {
            InitializeComponent();
        }
private void Form1_Load(object sender, EventArgs e)
        {
            
try
            {
                Smark.SocketAsyncs.Utils.AsyncEventArgsPool_MAX 
= 10;
                Client 
= new SocketAsyncsForNorthwind.Modules.NorthWindClient(Functions.AppSettingValue("ip"), Functions.AppSettingValue<int>("port"));
                dataGridView1.DataSource 
= Client.ListEmployees(nullnullnull);
            }
            
catch (Exception e_)
            {
                MessageBox.Show(e_.Message);
            }
        }
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
        {
            
if (dataGridView1.SelectedRows.Count>0)
            {
                Modules.Employees emp 
= (Modules.Employees)dataGridView1.SelectedRows[0].DataBoundItem;
                propertyGrid1.SelectedObject 
= Client.LoadEmployee(emp.EmployeeID);
            }
        }
private void button1_Click(object sender, EventArgs e)
        {
            
try
            {
            dataGridView1.DataSource 
= Client.ListEmployees(textBox1.Text, textBox2.Text, textBox3.Text);
            }
            
catch (Exception e_)
            {
                MessageBox.Show(e_.Message);
            }
        }      
    }

相关程序代码:[url:https://smark.svn.codeplex.com/svn/Samples/SocketAsyncsForNorthwind/]

4)简单负载测试

  测试用例获取所有Employee数据