텔넷 클라이언트에서 지속적인 정보 추출

텔넷 클라이언트에서 지속적인 정보 추출

인터페이스 모듈을 통해 원시 값을 제공하는 산업용 센서가 있습니다 telnet.

연결하려면 다음 단계를 따르세요.

  telnet 169.254.168.150 10001

나는 그것에서 쓰레기 값만 볼 수 있습니다.

정보

내가 가지고 있는 정보는 인터페이스 모듈의 데이터시트에서 나온 것입니다.

센서는 아날로그 센서이므로 Status플래그는 관련이 없습니다.

데이터 형식

저는 센서 정보를 시각화할 수 있는 이 회사의 독점 소프트웨어를 가지고 있습니다. 이 소프트웨어는 위에서 언급한 텔넷 프로토콜을 사용하여 정보를 얻습니다. WireShark를 통해 교차 확인했습니다. 패킷 크기는 리틀 엔디안 순서로 22바이트입니다.

Wireshark 덤프

내 정보를 프로그래밍 방식으로 가져올 수 없습니다.SE 쿼리값을 얻고 싶습니다. 전달된 값을 어딘가(데이터베이스 또는 파일)에 직접 저장할 수 있습니다.

명령줄을 통해 이 정보를 추출할 수 있는 방법이 있습니까?

답변1

Pastebin에서 추출됨:

00000050  2e 0a 53 41 45 4d 00 00  00 00 f6 04 00 00 15 00  |..SAEM..........|
00000060  00 00 00 00 00 00 00 00  00 00 0c 00 01 00 fa 94  |................|
00000070  00 00 8c 00 00 00 8c 00  00 00 0a 23 00 00 53 41  |...........#..SA|
00000080  45 4d 00 00 00 00 f6 04  00 00 15 00 00 00 00 00  |EM..............|

따라서 이는 정보가 모두 있고 리틀 엔디안이므로 읽고 구문 분석하기만 하면 된다는 것을 보여줍니다. 당신에게 익숙한 어떤 도구라도 C 프로그램, perl프로그램 등 당신이 원하는 모든 것을 할 수 있습니다. telnet선행 출력을 건너뛰거나 대신 다른 출력을 사용해야 할 수도 있습니다 telnet(예 nc: , netcat, socat).

시연하고 perl패킷을 디코딩하려면 다음과 같은 작업을 수행합니다.

cat ... | perl -nle "print join(':',unpack 'a4 (L2 Q L S2 l4)<')"

덤프에 있는 패킷의 명령줄에서 출력을 얻습니다.

SAEM:0:1270:21:0:12:1:38138:140:140

이는 지정된 수의 채널에 대해서만 작동합니다. 마스크는 4개 측정 중 하나가 없어야 함을 나타내지만 값이 있습니다. 해당 부분을 이해하지 못합니다.

다른 정보를 기반으로 다양한 수의 채널을 얻는 경우 더 스마트한 구문 분석이 필요합니다.

답변2

그래서 나는 분명히 그 반대라고 생각합니다. Wireshark에서 데이터를 캡처하고 있으므로 모든 패킷은 (세션 시작 정보) tcp이고 처음 몇 개의 패킷만 있습니다.telnet

나는 Python을 사용하여 소켓을 만들고 tcp22바이트의 데이터를 읽기로 결정했습니다(Wireshark Dump에서 사용 가능한 크기).

struct정보를 얻기 위해 모듈을 사용합니다 unpack. 유용한 센서 정보가 항상 대체 TCP 페이로드로 제공된다는 사실은 흥미롭습니다. 즉, 첫 번째 패킷에는 다음 정보만 포함됩니다.머리말,기사 ID,일련번호잠깐, 다음 페이로드에는 모든 정보가 포함되어 있습니다 Counter.채널 1 값,채널 2 값,채널 3 값

여기서 얻은 정보는 int32모듈 매뉴얼에 언급된 공식을 사용하여 적절한 값으로 변환되어야 합니다.

암호

import socket
import struct

# CONSTANTS for Formula
# ....

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_address = ('169.254.168.150', 10001)
print('connecting to %s port %s' % server_address)
sock.connect(server_address)


def value_mm(raw_val):
""" Formula for conversion """
    return (((raw_val - DRANGEMIN) * MEASRANGE) / (DRANGEMAX - DRANGEMIN) + OFFSET)


if __name__ == '__main__':
    while True:
        Laser_Value = 0
        data = sock.recv(22)
        # First frame
        preamble, article, serial, x1, x2 = struct.unpack('<4sIIQH', data)

        # if this payload is not the preamble, it must be information payload
        if not preamble == b'SAEM':
            status, bpf, mValCounter, CH1, CH2, CH3 = struct.unpack('<hIIIII',data)
            #print(CH1, CH2, CH3)
            Laser_Value = CH3
            print(str(value_mm(Laser_Value)) + " mm")

        print('\n')

관련 정보