Пример #1
0
 /// <summary>
 /// Parses a telegram received by ReceiveTelegram.
 /// </summary>
 /// <param name="buffer">Buffer containing the data.</param>
 /// <param name="telegramLength">Total length of the telegram in bytes.</param>
 /// <param name="isResponse">true if the telegram is a response telegram; false if the telegram is a request telegram.</param>
 /// <param name="telegramContext">
 /// If isResponse == true: pass the telegramContext returned by CreateTelegram from the request.
 /// If isResponse == false: returns the telegramContext from the received request. It must pe passed to the CreateTelegram method for the response.
 /// </param>
 /// <param name="address">Returns the device address.</param>
 /// <param name="fkt">Returns the function code.</param>
 /// <param name="dataPos">Returns the offset in buffer of the function code specific data.</param>
 /// <param name="dataLength">Returns the length of the function code specific data.</param>
 /// <returns>Returns true if this is the matching response according to the telegramContext; else false. If isResponse == false this method should return always true.</returns>
 public bool ParseTelegram(byte[] buffer, short telegramLength, bool isResponse, ref object telegramContext, out byte address,
                           out byte fkt, out short dataPos, out short dataLength)
 {
     if (telegramLength < 8)
     {
         throw new ModbusException(ModbusErrorCode.ResponseTooShort);
     }
     if (isResponse)
     {
         if (telegramContext is ushort)
         {
             ushort transactionId = ModbusUtils.ExtractUShort(buffer, 0);
             if (transactionId != (ushort)telegramContext)
             {
                 // telegram does not match
                 address    = 0;
                 fkt        = 0;
                 dataPos    = 0;
                 dataLength = 0;
                 return(false);
             }
         }
     }
     else
     {
         telegramContext = ModbusUtils.ExtractUShort(buffer, 0);
     }
     address    = buffer[6];
     fkt        = buffer[7];
     dataPos    = 8;
     dataLength = (short)(telegramLength - 8);
     return(true);
 }
Пример #2
0
        /// <summary>
        /// Waits and receives a telegram.
        /// </summary>
        /// <param name="buffer">Buffer to write data into.</param>
        /// <param name="desiredDataLength">Desired length of the function code specific data in bytes. -1 if length is unknown.</param>
        /// <param name="timeout">Timeout in milliseconds to wait for the telegram.</param>
        /// <param name="telegramLength">Returns the total length of the telegram in bytes.</param>
        /// <returns>Returns true if the telegram was received successfully; false on timeout.</returns>
        public bool ReceiveTelegram(byte[] buffer, short desiredDataLength, int timeout, out short telegramLength)
        {
            if (_Socket == null)
            {
                throw new ObjectDisposedException("ModbusTcp interface");
            }
            if (!_Socket.Poll(timeout * 1000, SelectMode.SelectRead) || _Socket.Available == 0)
            {
                telegramLength = 0;
                return(false);
            }
            // get the 1st 6 bytes, which includes the remaining length
            int pos = 0;

            while (pos < 6)
            {
                pos += _Socket.Receive(buffer, pos, 6 - pos, SocketFlags.None);
            }
            telegramLength = (short)(ModbusUtils.ExtractUShort(buffer, 4) + 6);

            // receive remaining data
            while (pos < telegramLength)
            {
                pos += _Socket.Receive(buffer, pos, telegramLength - pos, SocketFlags.None);
            }
            return(true);
        }