From 5685dda17b86eece70486418a6f94544f3fc9311 Mon Sep 17 00:00:00 2001 From: fcolin Date: Thu, 1 Feb 2007 10:01:42 +0000 Subject: Utilisateur : Fcolin Date : 19/12/05 Heure : 16:54 Créé Commentaire: (vss 1) --- CSharp/Ivy/IvyPPC/IvyTCPStreamV3.cs | 277 ++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 CSharp/Ivy/IvyPPC/IvyTCPStreamV3.cs (limited to 'CSharp') diff --git a/CSharp/Ivy/IvyPPC/IvyTCPStreamV3.cs b/CSharp/Ivy/IvyPPC/IvyTCPStreamV3.cs new file mode 100644 index 0000000..12a204e --- /dev/null +++ b/CSharp/Ivy/IvyPPC/IvyTCPStreamV3.cs @@ -0,0 +1,277 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Collections; +using System.Collections.Specialized; +using System.IO; + +namespace IvyBus +{ + /// + /// Description résumée de IvyStream. + /// + internal class IvyTCPStreamV3 : IvyTCPStream + { + StreamReader input; + StreamWriter output; + IvyProtocolInterface receiver; + + /// the protocol separator + internal const char ARG_START = '\x02'; + internal const char ARG_END = '\x03'; + internal const char MSG_END = '\n'; + + internal IvyTCPStreamV3(Socket socket, IvyProtocolInterface _receiver) : base ( socket ) + { + output = new StreamWriter(stream, Encoding.ASCII); + output.NewLine = MSG_END.ToString(); + input = new StreamReader(stream, Encoding.ASCII); + receiver = _receiver; + } + /* the protocol magic numbers */ + internal enum MessageType : ushort + { + Bye = 0, /* end of the peer */ + AddRegexp = 1, /* the peer adds a regexp */ + Msg = 2, /* the peer sends a message */ + Error = 3, /* error message */ + DelBinding = 4, /* the peer removes one of his regex */ // OLD DelRegexp rename to DelBinding + EndRegexp = 5, /* no more regexp in the handshake */ + StartRegexp = 6, /* avoid race condition in concurrent connexions */ + DirectMsg = 7, /* the peer sends a direct message */ + Die = 8, /* the peer wants us to quit */ + Ping = 9, /* checks the presence of the other */ + Pong = 10, /* checks the presence of the other */ + }; + + /* + * message Syntax: + * this is a binary formated message use of network representation + * + * message Format: + MessageType, id , length, string + */ + private void Serialize(ushort arg, char sep) + { + output.Write(arg); + output.Write(sep); + } + private void Serialize(string arg, char sep) + { + output.Write(arg); + output.Write(sep); + } + private void Serialize(string[] arg, char sep) + { + /* serialize value */ + //Serialize(arg.Value); + + /* serialize children */ + //Serialize((short)arg.Count); + for (int i = 0; i < arg.Length; i++) + { + Serialize(arg[i], sep); + } + } + private void sendMsg(MessageType msgType, ushort msgId,params string[] msgData) + { + + Console.WriteLine(" sendMsg {0} id={1} data={2}", msgType, msgId, msgData); + Serialize((ushort)msgType, ' '); + Serialize(msgId, ARG_START); + Serialize(msgData, ARG_END); + output.Write(MSG_END); + output.Flush(); + } + public override void TokenStartRegexp(ushort port, string appName) + { + sendMsg(MessageType.StartRegexp, port, appName); + } + public override void TokenEndRegexp() + { + sendMsg(MessageType.EndRegexp, 0, ""); + } + public override void TokenApplicationId(ushort priority, string appId) + { + // NOt implemented in this protocol version + } + + public override void TokenAddRegexp(ushort id, string bind) + { + sendMsg(MessageType.AddRegexp, id, bind); /* perhaps we should perform some checking here */ + } + public override void TokenAddBinding(ushort id, string bind) + { + // NOt implemented in this protocol version + } + + public override void TokenDelBinding(ushort id) + { + sendMsg(MessageType.DelBinding, id, ""); + } + + public override void TokenDirectMsg(ushort id, string message) + { + sendMsg(MessageType.DirectMsg, id, message); + } + public override void TokenPong(string s) + { + sendMsg(MessageType.Pong, 0, s); + } + public override void TokenPing(string s) + { + sendMsg(MessageType.Ping, 0, s); + } + + public override void TokenBye(ushort id, string message) + { + sendMsg(MessageType.Bye, id, message); + } + + public override void TokenDie(ushort id, string message) + { + sendMsg(MessageType.Die, id, message); + } + + public override void TokenMsg(ushort key, string[] args) + { + sendMsg(MessageType.Msg, key, args); + } + + public override void TokenError(ushort key, string arg) + { + sendMsg(MessageType.Msg, key, arg); + } + + private ushort DeserializeShort() + { + int read; + ushort ret = 0; + char digit; + // this will eat next non digit char ie space + do + { + read = input.Read(); + if (read < 0) break; + digit = (char)read; + if (Char.IsDigit(digit)) + ret = (ushort)(ret * 10 + (digit - 0x30)); + } while (Char.IsDigit(digit)); + return ret; + } + private string DeserializeString(char sep,char eol_sep, out bool eol) + { + int read; + char car = eol_sep; + StringBuilder str = new StringBuilder(); + // this will eat next non separator char + do + { + read = input.Read(); + if (read < 0) break; + car = (char)read; + if (car != sep && car != eol_sep) str.Append(car); + } while (car != sep && car != eol_sep); + eol = car == eol_sep || (read < 0 ); + return str.ToString(); + } + + + private string[] DeserializeArgument() + { + StringCollection coll; + string[] args; + string str; + bool eol; + + coll = new StringCollection(); + do + { + str = DeserializeString(ARG_END, MSG_END, out eol); + coll.Add(str); + } while (!eol); + args = new string[coll.Count]; + coll.CopyTo(args, 0); + return args; + } + internal override bool receiveMsg() + { + MessageType msgType = MessageType.Die; + ushort msgId = 0; + string[] msgData = null; + + try + { + msgType = (MessageType)DeserializeShort(); + msgId = DeserializeShort(); + msgData = DeserializeArgument(); + Console.WriteLine(" receiveMsg {0} id={1} data={2}", msgType, msgId, msgData); + switch (msgType) + { + case MessageType.Die: + receiver.TokenDie(msgId, msgData[0]); + break; + + case MessageType.Bye: + receiver.TokenBye(msgId, msgData[0]); + break; + + case MessageType.AddRegexp: + receiver.TokenAddRegexp(msgId, msgData[0]); + break; + + case MessageType.DelBinding: + receiver.TokenDelBinding(msgId); + break; + + case MessageType.EndRegexp: + receiver.TokenEndRegexp(); + break; + + case MessageType.Msg: + receiver.TokenMsg(msgId, msgData); + break; + + case MessageType.Pong: + receiver.TokenPong(msgData[0]); + break; + + case MessageType.Ping: + receiver.TokenPing(msgData[0]); + break; + + case MessageType.Error: + receiver.TokenError(msgId, msgData[0]); + break; + + case MessageType.StartRegexp: + receiver.TokenStartRegexp(msgId, msgData[0]); + break; + + case MessageType.DirectMsg: + receiver.TokenDirectMsg(msgId, msgData[0]); + break; + default: + throw new IvyException("protocol error, unknown message type " + msgType); + + } + + + + } + catch (EndOfStreamException nfe) + { + return false; + } + catch (FormatException nfe) + { + throw new IvyException("protocol error on msgType"); + } + + + return true; + } + + } +} -- cgit v1.1