项目需要,最近在着手开发的一个网站队列处理系统的一个网络模块
2011-01-24 16:06
1016 查看
其中使用到了Socket的非阻塞方法来接受数据,然后交由另一个线程进行命令的解释(只是将命令整条提取出来放入队列或者列表中),客户端测试程序有空再放出吧,测试的话用网络调试软件发ascii字符就可以
[6]abcd12
6为长度
abcd12为命令字符串(提取到队列或列表中的部分)
[6]abcd12
6为长度
abcd12为命令字符串(提取到队列或列表中的部分)
using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Data; using System.Collections.Generic; using System.Text.RegularExpressions; // State object for reading client data asynchronously public class StateObject { // Client socket. public Socket workSocket = null; // Size of receive buffer. public const int BufferSize = 1024; // Receive buffer. public byte[] buffer = new byte[BufferSize]; // Received data string. public StringBuilder sb = new StringBuilder(); // Offset public int counter = 0; // public bool isDisconnected = false; // public Thread dataParseThread = null; // public ManualResetEvent readDone = new ManualResetEvent(false); // public ManualResetEvent ProcessDone = new ManualResetEvent(false); } public class AsynchronousSocketListener { public static int Main(String[] args) { //StartListening(); AsyncSocketServer asyncServer = new AsyncSocketServer(); asyncServer.StartListening(); return 0; } } public class AsyncSocketServer { // Thread signal. private ManualResetEvent allDone = new ManualResetEvent(false); public AsyncSocketServer() { } public void StartListening() { // Data buffer for incoming data. byte[] bytes = new Byte[1024]; // Establish the local endpoint for the socket. // The DNS name of the computer // running the listener is "host.contoso.com". IPHostEntry ipHostInfo = Dns.GetHostEntry("127.0.0.1"); IPAddress ipAddress = ipHostInfo.AddressList[0]; IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000); // Create a TCP/IP socket. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // Bind the socket to the local endpoint and listen for incoming connections. try { listener.Bind(localEndPoint); listener.Listen(10); while (true) { // Set the event to nonsignaled state. allDone.Reset(); // Start an asynchronous socket to listen for connections. Console.WriteLine("Waiting for a connection..."); listener.BeginAccept( new AsyncCallback(AcceptCallback), listener); // Wait until a connection is made before continuing. allDone.WaitOne(); } } catch (Exception e) { Console.WriteLine(e.ToString()); } Console.WriteLine("/nPress ENTER to continue..."); Console.Read(); } public void AcceptCallback(IAsyncResult ar) { // Signal the main thread to continue. allDone.Set(); // Get the socket that handles the client request. Socket listener = (Socket)ar.AsyncState; Socket handler = listener.EndAccept(ar); // Create the state object. StateObject state = new StateObject(); state.workSocket = handler; DataProcessor dateProcessor = new DataProcessor(state); Thread t = new Thread(dateProcessor.ParseRowData); state.dataParseThread = t; t.Start(); IAsyncResult iar = handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } public void ReadCallback(IAsyncResult ar) { String content = String.Empty; // Retrieve the state object and the handler socket // from the asynchronous state object. StateObject state = (StateObject)ar.AsyncState; Socket handler = state.workSocket; try { // Read data from the client socket. int bytesRead = handler.EndReceive(ar); if (bytesRead <= 0) { Console.WriteLine("Server can't handle because received data length is zero..."); handler.Shutdown(SocketShutdown.Both); handler.Close(); return; } state.readDone.Reset(); string tmp = System.Text.Encoding.ASCII.GetString(state.buffer, 0, bytesRead); state.sb.Append(tmp); Console.WriteLine(state.sb.ToString()); state.ProcessDone.Set(); state.readDone.WaitOne(); IAsyncResult iar = handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } catch (Exception ex) { ; } } private void Send(Socket handler, String data) { // Convert the string data to byte data using ASCII encoding. byte[] byteData = Encoding.ASCII.GetBytes(data); // Begin sending the data to the remote device. handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler); } private void SendCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. Socket handler = (Socket)ar.AsyncState; // Complete sending the data to the remote device. int bytesSent = handler.EndSend(ar); Console.WriteLine("Sent {0} bytes to client.", bytesSent); handler.Shutdown(SocketShutdown.Both); handler.Close(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } } public class DataProcessor { private StateObject st = null; // hold command txt private static List<string> commandQueue = new List<string>(); public DataProcessor(StateObject st) { this.st = st; } // private Mutex addCommandMutex = new Mutex(false, "MUTEX_ADD_COMMAND"); public void ParseRowData() { Regex regex = new Regex(@"/[([/d]+)/]"); while (true) { st.ProcessDone.WaitOne(); if (st.sb.Length > 0) { Console.WriteLine("Start to parse data..."); string tmp = st.sb.ToString(); Match match = regex.Match(tmp); if (match.Success == false) Console.WriteLine("Not matched..."); while (match.Success) { string strLen = match.Groups[1].Value; int len = int.Parse(strLen); string strMatch = match.ToString(); if (tmp.Length - strMatch.Length - match.Index >= len) { string strToAdd = tmp.Substring(strMatch.Length + match.Index, len); Console.WriteLine("Adding command: " + strToAdd); AddToCommandQueue(strToAdd); st.sb.Remove(0, match.Index + strMatch.Length + len); } else { Console.WriteLine("The string is not completed, waiting the reset data..."); break; } PrintCommandQueue(); tmp = st.sb.ToString(); match = regex.Match(tmp); } Console.WriteLine("End parsing data..."); } else { Console.WriteLine("No data will be processed..."); } st.readDone.Set(); st.ProcessDone.Reset(); } } private void AddToCommandQueue(string str) { addCommandMutex.WaitOne(); commandQueue.Add(str); addCommandMutex.ReleaseMutex(); } public static void PrintCommandQueue() { foreach(string item in commandQueue) { Console.WriteLine(item); } } }
相关文章推荐
- 项目需要,最近在着手开发的一个网站队列处理系统的一个网络模块
- 由于最近网站内容需要更新的还是满多的,于是想开发一个采集系统。收集了一下资料。
- Python 最近因开发项目的需要,有一个需求,就是很多SNS网站都有的通过 Email地址 导入好友列表,不过这次要导入的不是Email 列表,而是QQ的好友列表。 实现方式: 通过goog
- 项目需要,正好也学习jsp,就用jsp开发一个带会员系统的企业站
- [置顶] 在着手准备做一个开发项目(web前端),需要做哪些准备?
- 最近项目要求开发一个echarts的小功能图表,需要动态加载数据,现在做完后把源码拷上来
- 最近一个项目用到PostgresSQl数据库,有些不同于oracle数据库,尤其时间处理上,结合PostgreSQL手册以及网上转载些资料,如下,方便开发中用到
- 移动项目开发笔记(禁止一个按钮在服务器事件处理完成前连续点击按钮)
- Android网络编程之一个Android下菜单系统模块的实现(服务器端—结算功能(下部))
- 互联网项目开发效率与系统性能的一个取舍问题
- 【小松教你手游开发】【系统模块开发】做一个3d旋转菜单
- 通过一个简单的文章系统学习MVC3+Linq搭建网站--项目文件结构介绍(3)
- 做项目的研发模式,即怎么研发一个系统,一步一步怎么做:UP、RUP、迭代式、瀑布式、快速原型、敏捷开发,区别
- Android网络编程之一个Android下菜单系统模块的实现(客户端—开桌功能(上部))
- 如果我新接一个做到一半的项目,或者需要二次开发的项目我希望了解的内容有哪些?
- 网站系统开发需要掌握的技术
- 最近接一个华技CMES协同系统开发对接的项目,顺利完成开发对接
- Asp.net MVC 3 开发一个简单的企业网站系统
- 写复杂的网络交互系统模块时需要考虑什么
- JavaWeb项目开发案例精粹-第4章博客网站系统-003Dao层