From 92757a8d629812303ff3665343bd098917cca611 Mon Sep 17 00:00:00 2001 From: fcolin Date: Thu, 1 Feb 2007 12:04:16 +0000 Subject: modification structure svn --- Ivy/IvyTCPStreamV4.cs | 273 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 273 insertions(+) create mode 100644 Ivy/IvyTCPStreamV4.cs (limited to 'Ivy/IvyTCPStreamV4.cs') diff --git a/Ivy/IvyTCPStreamV4.cs b/Ivy/IvyTCPStreamV4.cs new file mode 100644 index 0000000..9a96d62 --- /dev/null +++ b/Ivy/IvyTCPStreamV4.cs @@ -0,0 +1,273 @@ +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 IvyTCPStreamV4 : NetworkStream , IvyProtocol + { + BinaryReader input; + BinaryWriter output; + IvyProtocol 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 */ + ApplicationId = 11, /* on start send my ID and priority */ + AddBinding = 12, /* other methods for binding message based on hash table */ + + }; + + internal IvyTCPStreamV4(Socket socket, IvyProtocol _receiver) : base( socket ) + { + + input = new BinaryReader(this, Encoding.ASCII); + output = new BinaryWriter(this, Encoding.ASCII); + receiver = _receiver; + } + + + /* + * message Syntax: + * this is a binary formated message use of network representation + * + * message Format: + MessageType, id , length, string + */ + private void Serialize(short arg) + { + output.Write((ushort)IPAddress.HostToNetworkOrder(arg)); + } + private void Serialize(string arg) + { + short length = arg != null ? (short)arg.Length : (short)0; + Serialize(length); + if (length != 0) + output.Write(arg.ToCharArray()); + } + private void Serialize(string[] arg) + { + + /* serialize count */ + Serialize((short)arg.Length); + + for (int i = 0; i < arg.Length; i++) + { + Serialize(arg[i]); + } + } + private void sendMsg(MessageType type, int id, params string[] arg) + { + + Serialize( (short)type ); + Serialize( (short)id ); + Serialize(arg); + output.Flush(); + + } + void IvyProtocol.TokenStartRegexp(ushort port, string appName) + { + sendMsg(MessageType.StartRegexp, port, appName); + } + void IvyProtocol.TokenEndRegexp() + { + sendMsg(MessageType.EndRegexp, 0, ""); + } + void IvyProtocol.TokenApplicationId(ushort priority, string appId) + { + sendMsg(MessageType.ApplicationId, priority, appId); + } + + void IvyProtocol.TokenAddBinding(BindingType type, ushort id, string expression) + { + switch (type) + { + case BindingType.Regexp: + sendMsg(MessageType.AddRegexp, id, expression); /* perhaps we should perform some checking here */ + break; + case BindingType.Simple: + sendMsg(MessageType.AddBinding, id, expression); /* perhaps we should perform some checking here */ + break; + } + } + + void IvyProtocol.TokenDelBinding(ushort id) + { + sendMsg(MessageType.DelBinding, id, null ); + } + + void IvyProtocol.TokenDirectMsg(ushort id, string message) + { + sendMsg(MessageType.DirectMsg, id, message); + } + void IvyProtocol.TokenPong(string s) + { + sendMsg(MessageType.Pong, 0, s); + } + void IvyProtocol.TokenPing(string s) + { + sendMsg(MessageType.Ping, 0, s); + } + + void IvyProtocol.TokenBye(ushort id, string message) + { + sendMsg(MessageType.Bye, id, message); + } + + void IvyProtocol.TokenDie(ushort id, string message) + { + sendMsg(MessageType.Die, id, message); + } + + void IvyProtocol.TokenMsg(ushort key, string[] args) + { + sendMsg(MessageType.Msg, key, args ); + } + + void IvyProtocol.TokenError(ushort key, string arg) + { + sendMsg(MessageType.Msg, key, arg); + } + + private short DeserializeShort() + { + return IPAddress.NetworkToHostOrder((short)input.ReadUInt16()); + } + private string DeserializeString() + { + string arg; + int val_len; + char[] data; + val_len = (ushort)DeserializeShort(); + if (val_len != 0) + { + data = input.ReadChars(val_len); + arg = new String(data); + } + else + arg = ""; + return arg; + } + + + private string[] DeserializeArgument() + { + int nb_children; + string[] arg; + + /* Deserialize childrens */ + nb_children = (ushort)DeserializeShort(); + /* deserialize Value */ + arg = new string[nb_children]; + + for (int i = 0; i < nb_children; i++) + { + arg[i] = DeserializeString(); + } + return arg; + } + bool IvyProtocol.receiveMsg() + { + MessageType msgType = MessageType.Die; + ushort msgId = 0; + string[] msgData = null; + + try + { + msgType = (MessageType)(ushort)DeserializeShort(); + msgId = (ushort)DeserializeShort(); + msgData = DeserializeArgument(); + + switch (msgType) + { + case MessageType.Die: + receiver.TokenDie(msgId, msgData[0]); + break; + + case MessageType.Bye: + receiver.TokenBye(msgId, msgData[0]); + break; + + case MessageType.AddRegexp: + receiver.TokenAddBinding(BindingType.Regexp, msgId, msgData[0]); + break; + + case MessageType.AddBinding: + receiver.TokenAddBinding(BindingType.Simple, 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; + case MessageType.ApplicationId: + receiver.TokenApplicationId(msgId, msgData[0]); + break; + default: + throw new IvyException("protocol error, unknown message type " + msgType); + + } + + + + } + catch (EndOfStreamException) + { + return false; + } + catch (FormatException) + { + throw new IvyException("protocol error on msgType"); + } + + + return true; + } + + } +} -- cgit v1.1