/// <summary> /// ����ִ�к���,������֡ʱ�������ݻ��� /// </summary> /// <param name="client">ͨѶ����</param> /// <param name="data">������������</param> /// <param name="bufferStream">�����ֽ���</param> /// <returns>������Ӧ����,֡����������0�ֽ�,����������ִ֡�к���Ӧ���</returns> public override byte[] Execute(ClientInfo clientinfo, byte[] data, int len, ref MemoryStream stream) { IList<byte[]> list = new List<byte[]>(); byte[] buffer = new byte[0]; //û��ͷ��Ϣ�ģ������ֽںϲ�����ͷ��Ϣ if (stream.Position < 1) { buffer = new byte[stream.Length + len]; stream.Read(buffer, 0, (int)stream.Length); Array.Copy(data, 0, buffer, stream.Length, len); } else { //��ȡ������ͷ��Ϣ,ֱ�Ӷ����� int pos = (int)stream.Position; buffer = new byte[pos]; stream.Seek(0, SeekOrigin.Begin); stream.Read(buffer, 0, pos); NameValueCollection info = ParseInfo(buffer); long flen = Convert.ToInt64(info["len"]); stream.Seek(0, SeekOrigin.End); //���ֽ����������� if (flen > stream.Length + len - pos) { stream.Write(data, 0, len); stream.Seek(pos, SeekOrigin.Begin); return new byte[0]; } int lennext = (int)(stream.Length + len - pos - flen); if (lennext > len) { //�ϴ������Ѿ���������Ϣ buffer = new byte[pos + flen]; stream.Seek(0, SeekOrigin.Begin); stream.Read(buffer, 0, buffer.Length); list.Add(buffer); buffer = new byte[lennext]; stream.Read(buffer, 0, (int)stream.Length - pos - (int)flen); Array.Copy(data, buffer, len); } else { //���ֽ��������ֽڼ����б�,�����ֽڼ�������ͷ��Ϣ if (len > lennext) stream.Write(data, 0, len - lennext); list.Add(stream.ToArray()); buffer = new byte[lennext]; Array.Copy(data, len - lennext, buffer, 0, lennext); } } buffer = MergeResponseHdl(buffer, list); if (stream.Length > 0 || buffer.Length > 0) { stream = new MemoryStream(buffer); data = GetFileheader(buffer); if (null != data && data.Length > 0) stream.Seek(data.Length, SeekOrigin.Begin); } for (int i = list.Count - 1; i > -1; i--) { byte[] context = list[i]; byte[] header = GetFileheader(context); NameValueCollection info = ParseInfo(header); RequestEventArgs args = new RequestEventArgs(null, this, context); int rtn = this.RaiseRequest(args); string keycmd = info["cmd"]; if (string.IsNullOrEmpty(keycmd) || !this.CmdMap.ContainsKey(keycmd)) { list.RemoveAt(i); continue; } if (rtn < 0) continue; HdlExecute hdl = this.CmdMap[info["cmd"]]; //ִ��ָ���ȡ��Ӧ��� try { list[i] = hdl(clientinfo, context); } catch (Exception ex) { ExceptionManager.Publish(ex); list.RemoveAt(i); } } //�����Ӧ if (list.Count < 1) return new byte[0]; if (list.Count < 2) return list[0]; //�������ʱ�ϲ�����ֽ� long lend = 0; foreach (byte[] b in list) lend += b.LongLength; data = new byte[lend]; lend = 0; foreach (byte[] b in list) { Array.Copy(b, 0, data, lend, b.LongLength); lend += b.LongLength; } return data; }
/// <summary> /// ��������ȡͨѶ���� /// </summary> /// <param name="client">�ͻ�������</param> /// <param name="server">������</param> private void readData(ClientInfo clientinfo, ServerBase server) { if (null == clientinfo || null == server) return; Socket client = clientinfo.Client; bool isopen = false; int iM = 1048576, available = 0; try { isopen = client.Connected; available = isopen ? client.Available : 0; } catch { return; } List<byte[]> responseList = clientinfo.BufferResponse; byte[] buffer = new byte[client.ReceiveBufferSize]; MemoryStream stream = new MemoryStream(); byte[] b = null; while (true) { while (available > 0) { try { //ִ������ byte[] request = stream.ToArray(); long pos = stream.Position; int len = client.Receive(buffer); available = client.Available; clientinfo.OPdt = DateTime.Now; if (request.Length > 0) { stream = new MemoryStream(); long lenr = request.LongLength; for (int i = 0; i * iM < lenr; i++) stream.Write(request, iM * i, lenr > (i + 1) * iM ? iM : (int)(lenr - i * iM)); } stream.Seek(pos, SeekOrigin.Begin); byte[] reqarg = new byte[len]; Array.Copy(buffer, reqarg, len); RequestEventArgs argreq = new RequestEventArgs(client, server, reqarg); this.raiseEvent(argreq); b = server.Execute(clientinfo, buffer, len, ref stream); } catch (Exception ex) { byte[] request = stream.ToArray(); stream = new MemoryStream(); ErrorRequestEventArgs argerr = new ErrorRequestEventArgs(client, server, request, ex); this.raiseEvent(argerr); if (ex is SocketException) { isopen = false; break; } continue; } //��Ӧ���д�뻺��,����ͬ���¼�д����Ӧ if (null != b && b.Length > 0) { Monitor.Enter(clientinfo); responseList.Add(b); Monitor.PulseAll(clientinfo); Monitor.Exit(clientinfo); } }//while (available > 0) while(available < 1) { Thread.Sleep(10); try { isopen = client.Connected; available = isopen ? client.Available : 0; if (!isopen) break; } catch { available = 0; isopen = false; break; } } if (!isopen) { this.closeClientInfo(clientinfo, server); return; } }//while (true) }
/// <summary> /// 重载执行函数,不完整帧时接收数据缓存 /// </summary> /// <param name="client">通讯连接</param> /// <param name="data">接收请求数据</param> /// <param name="bufferStream">缓存字节流</param> /// <returns>返回响应数据,帧不完整返回0字节,待接收完整帧执行后返回响应结果</returns> public override byte[] Execute(ClientInfo clientinfo, byte[] data, int len, ref MemoryStream stream) { IList<byte[]> list = new List<byte[]>(); byte[] buffer = new byte[0]; //没有头信息的,读入字节合并后检查头信息 int iM = 1048576; if (stream.Position < 1) { buffer = new byte[stream.Length + len]; long lenr = stream.Length; for (int i = 0; i * iM < lenr; i++) stream.Read(buffer, iM * i, lenr > (i + 1) * iM ? iM : (int)(lenr - i * iM)); Array.Copy(data, 0, buffer, stream.Length, len); } else { //读取数据流头信息,直接读入流 long pos = stream.Position; buffer = new byte[pos]; stream.Seek(0, SeekOrigin.Begin); for (int i = 0; i * iM < pos; i++) stream.Read(buffer, iM * i, pos > (i + 1) * iM ? iM : (int)(pos - i * iM)); NameValueCollection info = ParseInfo(buffer); long flen = Convert.ToInt64(info["len"]); stream.Seek(0, SeekOrigin.End); //大字节流继续读入 if (flen > stream.Length + len - pos) { stream.Write(data, 0, len); stream.Seek(pos, SeekOrigin.Begin); return new byte[0]; } long lennext = (stream.Length + len - pos - flen); if (lennext > len) { //上次流中已经有完整信息 long lenr = pos + flen; buffer = new byte[lenr]; stream.Seek(0, SeekOrigin.Begin); for (int i = 0; i * iM < lenr; i++) stream.Read(buffer, iM * i, lenr > (i + 1) * iM ? iM : (int)(lenr - i * iM)); list.Add(buffer); buffer = new byte[lennext]; lenr = stream.Length - pos - flen; for (int i = 0; i * iM < lenr; i++) stream.Read(buffer, iM * i, lenr > (i + 1) * iM ? iM : (int)(lenr - i * iM)); Array.Copy(data, buffer, len); } else { //大字节流完整字节加入列表,后续字节继续分析头信息 if (len > lennext) stream.Write(data, 0, len - (int)lennext); list.Add(stream.ToArray()); buffer = new byte[lennext]; Array.Copy(data, len - lennext, buffer, 0, lennext); } } buffer = MergeResponseHdl(buffer, list); if (stream.Length > 0 || buffer.Length > 0) { stream = new MemoryStream(buffer); data = GetFileheader(buffer); if (null != data && data.Length > 0) stream.Seek(data.LongLength, SeekOrigin.Begin); } for (int i = list.Count - 1; i > -1; i--) { byte[] context = list[i]; byte[] header = GetFileheader(context); NameValueCollection info = ParseInfo(header); RequestEventArgs args = new RequestEventArgs(null, this, context); int rtn = this.RaiseRequest(args); string keycmd = info["cmd"]; if (string.IsNullOrEmpty(keycmd) || !this.CmdMap.ContainsKey(keycmd)) { list.RemoveAt(i); continue; } if (rtn < 0) continue; HdlExecute hdl = this.CmdMap[info["cmd"]]; //执行指令获取响应结果 try { list[i] = hdl(clientinfo, context); } catch (Exception ex) { ExceptionManager.Publish(ex); list.RemoveAt(i); } } //输出响应 if (list.Count < 1) return new byte[0]; if (list.Count < 2) return list[0]; //多个请求时合并输出字节 long lend = 0; foreach (byte[] b in list) lend += b.LongLength; data = new byte[lend]; lend = 0; foreach (byte[] b in list) { Array.Copy(b, 0, data, lend, b.LongLength); lend += b.LongLength; } return data; }
/// <summary> /// 触发请求事件 /// </summary> /// <param name="arg">请求事件参数</param> /// <returns>返回-1则失败,不响应请求</returns> public virtual int RaiseRequest(RequestEventArgs arg) { EventHandler<RequestEventArgs> handle = this.RequestHandle; if (null != handle) { try { handle(this, arg); return arg.Return; } catch (Exception ex) { ExceptionManager.Publish(ex); return -1; } } return 0; }
/// <summary> /// 服务器读取通讯数据 /// </summary> /// <param name="client">客户端连接</param> /// <param name="server">服务器</param> private void readData(ClientInfo clientinfo, ServerBase server) { if (null == clientinfo || null == server) return; Socket client = clientinfo.Client; bool isopen = false; int iM = 1048576, available = 0; try { isopen = client.Connected; available = isopen ? client.Available : 0; } catch { return; } List<byte[]> responseList = clientinfo.BufferResponse; byte[] buffer = new byte[client.ReceiveBufferSize]; MemoryStream stream = new MemoryStream(); byte[] b = null; while (true) { while (available > 0) { try { //执行请求 byte[] request = stream.ToArray(); long pos = stream.Position; int len = client.Receive(buffer); string msgrp = Encoding.GetEncoding("GB2312").GetString(buffer, 0, len); Debug.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff") + " S接收:" + msgrp); myLog.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff") + " S接收:" + msgrp); clientinfo.OPdt = DateTime.Now; if (request.Length > 0) { stream = new MemoryStream(); long lenr = request.LongLength; for (int i = 0; i * iM < lenr; i++) stream.Write(request, iM * i, lenr > (i + 1) * iM ? iM : (int)(lenr - i * iM)); } stream.Seek(pos, SeekOrigin.Begin); byte[] reqarg = new byte[len]; Array.Copy(buffer, reqarg, len); RequestEventArgs argreq = new RequestEventArgs(client, server, reqarg); this.raiseEvent(argreq); b = server.Execute(clientinfo, buffer, len, ref stream); available = client.Available; } catch (Exception ex) { byte[] request = stream.ToArray(); stream = new MemoryStream(); //NameValueCollection attr = new NameValueCollection(); //attr["剩余连接数"] = Convert.ToString(server.ClientList.Count); //ExceptionManager.Publish(ex, attr); ErrorRequestEventArgs argerr = new ErrorRequestEventArgs(client, server, request, ex); this.raiseEvent(argerr); if (ex is SocketException) { isopen = false; break; } try { available = 0; isopen = client.Connected; available = isopen ? client.Available : 0; } catch { isopen = false; } continue; } //响应结果写入缓存,触发同步事件写入响应 if (null != b && b.Length > 0) { Monitor.Enter(clientinfo); responseList.Add(b); Monitor.PulseAll(clientinfo); Monitor.Exit(clientinfo); } }//while (available > 0) while(available < 1) { Thread.Sleep(10); try { isopen = client.Connected; available = isopen ? client.Available : 0; if (!isopen) break; } catch { available = 0; isopen = false; break; } } if (!isopen) { server.Close(clientinfo); return; } }//while (true) }