// Disconnects from the spread daemon. /** * Disconnects the connection to the daemon. Nothing else should be done with this connection * after disconnecting it. * * @throws SpreadException if there is no connection or there is an error disconnecting * @see SpreadConnection#connect(InetAddress, int, String, boolean, boolean) */ public void Disconnect() { // Check if we're connected. if (connected == false) { throw new SpreadException("Not connected."); } // Get a new message. SpreadMessage killMessage = new SpreadMessage(); // Send it to our private group. killMessage.AddGroup(group); // Set the service type. killMessage.ServiceType = SpreadMessage.KILL_MESS; // Send the message. Multicast(killMessage); // Close the socket. try { socket.Close(); } catch (Exception e) { throw new SpreadException("close(): " + e); } }
public void Join(SpreadConnection c, string groupName) { // Check if this group has already been joined. if (this.connection != null) { throw new SpreadException("Already joined."); } // Set member variables. this.connection = c; this.name = groupName; // Error check the name. byte[] bytes; try { bytes = System.Text.Encoding.ASCII.GetBytes(name); } catch (Exception e) { throw new SpreadException("Encoding not supported: " + e); } for (int i = 0; i < bytes.Length; i++) { // Make sure the byte (character) is within the valid range. if ((bytes[i] < 36) || (bytes[i] > 126)) { throw new SpreadException("Illegal character in group name."); } } // Get a new message. SpreadMessage joinMessage = new SpreadMessage(); // Set the group we're sending to. joinMessage.AddGroup(name); // Set the service type. joinMessage.ServiceType = SpreadMessage.JOIN_MESS; // Send the message. connection.Multicast(joinMessage); }
//------------------------------ Private ---------------------------------------- private void send(string pToGroup, string pMessage, bool pIsSelfDiscard) { SpreadMessage _spreadMsg = new SpreadMessage(); _spreadMsg.IsAgreed = true; // _spreadMsg.IsSafe = true; _spreadMsg.IsSelfDiscard = pIsSelfDiscard; _spreadMsg.AddGroup(pToGroup); _spreadMsg.Data = System.Text.Encoding.ASCII.GetBytes(pMessage); // Send msg and wait for response try { connection.Multicast(_spreadMsg); // if ( ! pIsSelfDiscard) { // SyncLock.Wait(); // } } catch (Exception _ex) { T.LogStatus("Multicast Exception: " + _ex); throw; } }
public void Leave() { // Check if we can leave. if (connection == null) { throw new SpreadException("No group to leave."); } // Get a new message. SpreadMessage leaveMessage = new SpreadMessage(); // Set the group we're sending to. leaveMessage.AddGroup(name); // Set the service type. leaveMessage.ServiceType = SpreadMessage.LEAVE_MESS; // Send the message. connection.Multicast(leaveMessage); // No longer connected. connection = null; }
private void AsyncReceive(IAsyncResult ar) { bool readAsync = false; do { if (receiveState == INIT_RECEIVE) { buffer = new byte[48]; receivedLength = 0; receiveState = HEADER_RECEIVE; receivedMessage = new SpreadMessage(); } else { if (receivedLength != buffer.Length) { int size = stream.EndRead(ar); if (size == 0) { throw new SpreadException("Connection closed while reading"); } receivedLength += size; } if (receivedLength == buffer.Length) { switch (receiveState) { case HEADER_RECEIVE: byte[] header = buffer; int headerIndex = 0; // Get service type. receivedMessage.ServiceType = toInt(header, headerIndex); headerIndex += 4; // Get the sender. receivedMessage.Sender = toGroup(header, headerIndex); headerIndex += MAX_GROUP_NAME; // Get the number of groups. numGroups = toInt(header, headerIndex); headerIndex += 4; // Get the hint/type. int hint = toInt(header, headerIndex); headerIndex += 4; // Get the data length. int dataLen = toInt(header, headerIndex); headerIndex += 4; // Does the header need to be flipped? // (Checking for a daemon server endian-mismatch) if (sameEndian(receivedMessage.ServiceType) == false) { // Flip them. receivedMessage.ServiceType = flip(receivedMessage.ServiceType); numGroups = flip(numGroups); dataLen = flip(dataLen); // The daemon endian-mismatch. daemonEndianMismatch = true; } else { // The daemon endian-mismatch. daemonEndianMismatch = false; } receivedMessage.Data = new byte[dataLen]; // Is this a regular message? if (receivedMessage.IsRegular || receivedMessage.IsReject) { // Does the hint need to be flipped? // (Checking for a sender endian-mismatch) if (sameEndian(hint) == false) { hint = flip(hint); receivedMessage.EndianMismatch = true; } else { receivedMessage.EndianMismatch = false; } // Get the type from the hint. hint = clearEndian(hint); hint >>= 8; hint &= 0x0000FFFF; receivedMessage.Type = (short)hint; } else { // This is not a regular message. receivedMessage.Type = -1; receivedMessage.EndianMismatch = false; } if (receivedMessage.IsReject) { buffer = new byte[4]; receivedLength = 0; receiveState = OLD_TYPE_RECEIVE; } else { buffer = new byte[numGroups * MAX_GROUP_NAME]; receivedLength = 0; receiveState = GROUPS_RECEIVE; } break; case OLD_TYPE_RECEIVE: int oldType = toInt(buffer, 0); if (sameEndian(receivedMessage.ServiceType) == false) { oldType = flip(oldType); } receivedMessage.ServiceType = (SpreadMessage.REJECT_MESS | oldType); buffer = new byte[numGroups * MAX_GROUP_NAME]; receivedLength = 0; receiveState = GROUPS_RECEIVE; break; case GROUPS_RECEIVE: // Clear the endian type. receivedMessage.ServiceType = clearEndian(receivedMessage.ServiceType); // Get the groups from the buffer. for (int bufferIndex = 0; bufferIndex < buffer.Length; bufferIndex += MAX_GROUP_NAME) { // Translate the name into a group and add it to the vector. receivedMessage.AddGroup(toGroup(buffer, bufferIndex)); } buffer = receivedMessage.Data; receivedLength = 0; receiveState = DATA_RECEIVE; break; case DATA_RECEIVE: // Is it a membership message? if (receivedMessage.IsMembership) { // Create a membership info object. receivedMessage.membershipInfo = new MembershipInfo(this, receivedMessage, daemonEndianMismatch); // Is it a regular membership message? if (receivedMessage.membershipInfo.IsRegularMembership) { // Find which of these groups is the local connection. receivedMessage.Type = (short)receivedMessage.groups.IndexOf(PrivateGroup); } } else { // There's no membership info. receivedMessage.membershipInfo = null; } if (OnRegularMessage != null && receivedMessage.IsRegular) { OnRegularMessage(receivedMessage); } else if (OnMembershipMessage != null && receivedMessage.IsMembership) { OnMembershipMessage(receivedMessage); } else { lock (rsynchro) { messageWaiting = true; Monitor.Pulse(rsynchro); Monitor.Wait(rsynchro); } } buffer = new byte[48]; receivedLength = 0; receiveState = HEADER_RECEIVE; receivedMessage = new SpreadMessage(); break; } } } try { // read sync if data available while (stream.DataAvailable && receivedLength < buffer.Length) { int size = stream.Read(buffer, receivedLength, buffer.Length - receivedLength); if (size == 0) { throw new SpreadException("Connection closed while reading"); } receivedLength += size; } if (receivedLength != buffer.Length) { // no more data - continue async read stream.BeginRead(buffer, receivedLength, buffer.Length - receivedLength, new AsyncCallback(AsyncReceive), null); readAsync = true; } } catch (Exception e) { throw new SpreadException("BeginRead(): " + e); } } while (!readAsync); }