2009-05-21 1 views
2

.net을 통해 직렬 포트를 통해 데이터를 보내는 데 새로운 것이므로 TCP 연결을 구현 한 후에 나타났습니다. 직렬로 쉽게 할 수 있어요!주로 여러 개의 "패킷"으로 수신 된 데이터가있는 .NET 직렬 포트 도움말이 필요합니다.

  1. 내 여러 메시지로 분할되거나 수신되는 읽기 -이 : 그래서

    내가 몇 가지에 붙어 무엇입니까 내 시리얼 양방향 통신 구현과 거의가 오전, 상단에 시작 COM 포트를 통한 조각화 된 응답으로 어떤 설정이 필요한지 또는이 문제를 해결하기 위해 코드를 어떻게 다르게 작성해야하는지 모릅니다. 무엇이 이것을 일으킬 수 있습니까?

    01: LS|DA090521|TI111 
    02: 043|q 
    03: PS|RN102|PTC|TA1 
    04: 0000|P#0|DA090521|TI111429|j 
    
    (읽기 요청 된 각 임의 위치에)

    01: LS|DA090521|TI111043|q 
    02: PS|RN102|PTC|TA1040000|P#0|DA090521|TI111429|j 
    

    하지만있는 분할이다 : 나는 기본적으로 데이터 SerialPort_DataReceived.

에 브레이크 포인트에서 메시지를 검사하고 같이 전송해야

- 질문 1이 답변되었습니다. Chris W. 님 외! 나는 이제 조각으로부터 점차적으로 만들어지기를 기대하는 메시지를 가지고있다. (STX, {msg body}, ETX를 찾는다.) 메시지가 완전히 만들어 졌을 때 수행되는 액션은 thread-safe Queue로 처리된다. .

. 2. 나는 "|" 기호는 거의 모든주기를 통해 읽습니다. 내가 잘못 설정 한 명령, 직렬 통신의 유물 또는 장치가 보내는 메시지로 인해 발생합니까? (나는 그렇게 생각하지 않는다. 하이퍼 터미널 연결이이 캐릭터가 계속적으로 보내지는 것을 드러낸다.)

. 3. 각 방법에서 데이터를 올바르게 읽고 쓰고 있는지 확인할 수 있습니까?

저의 다른 두 가지 질문에 대해서도 고마워요.

관련 코드를 다음과 같이

... 
    //       COM3, 9600,  None, 8,  One 
    SerialPort = new SerialPort(comPort, baudRate, parity, dataBits, stopBits); 
    if (SerialPort.IsOpen) SerialPort.Close(); 
    // SerialPort.RtsEnable = true; // Request-to-send 
    // SerialPort.DtrEnable = true; // Data-terminal-ready 
    SerialPort.ReadTimeout = 150; // tried this, but didn't help 
    SerialPort.WriteTimeout = 150; // tried this, but didn't help 
    SerialPort.Open(); 

    SerialPort.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived); 
} 

void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    // Process received data 
    SerialPort sp = (SerialPort)sender; 
    byte[] buffer = new byte[sp.BytesToRead]; 
    int bytesRead = sp.Read(buffer, 0, buffer.Length); 

    // message has successfully been received 
    message = Encoding.ASCII.GetString(buffer, 0, bytesRead); 
} 

public bool SendMessage(string text) 
{ 
    // Only send message if a client is connected 
    if (SerialPort != null && SerialPort.IsOpen) 
    { 
     byte[] buffer = Encoding.ASCII.GetBytes(text); 
     SerialPort.Write(buffer, 0, buffer.Length); 
    } 
} 

답변

4

내 여러 메시지

이 정상적인 예상, 피할 수없는 행동에 분할되고있다 읽습니다. TCP를 통한 데이터 오버 플로우에서도 발생할 수 있습니다. 시리얼 인터페이스는 끝이없는 바이트 스트림입니다. 이러한 바이트를 패킷으로 다시 패키징하는 것은 응용 프로그램의 책임입니다.

패킷 경계의 위치가 중요하고 패킷 경계가 수신 된 데이터를 볼 때 어디에 있어야하는지 알 수없는 경우 데이터의 형식을 다시 생각해야 할 수도 있습니다. 은 패킷 경계가 어디에 있는지 알려줍니다.

"|" 거의 모든주기를 통해 읽은 기호

그 문자의 16 진수 값은 무엇입니까? Handshake 속성을 XOnXOff 또는 RequestToSendXOnXOff으로 설정하면 상황이 개선되는지 확인하십시오.

+0

답장을 보내 주신 Chris에게 감사드립니다.좋아, 아마도 상자에 너무 많이 넣으려는 것입니다. 여러분이 말하는 것은 우리가 거의 자신의 '패킷 관리'를 할 필요가 있다는 것입니다. 부끄러운 점은 (아마도 몰랐습니다) 아마도 시리얼의 기초가 될 것입니다. 전송 후, msg 문자의 시작/끝 문자를 조사하고 포장하고 청소하고 헹구고 반복해야 할 수도 있습니다. – GONeale

+0

'|' 124 btw와 같습니다. – GONeale

+0

나는 그때를 모른다. 기본 XON/XOFF 값은 0x13 및 0x11입니다. - http://en.wikipedia.org/wiki/XON – ChrisW

3

낮은 레벨에서 직렬 포트는 데이터 수신 이벤트를 트리거 할시기를 결정할 수 있습니다. "전체"패킷이 도착하기 전에이를 결정할 수 있습니다. 그러나 예상 데이터 세트에 터미네이터 문자가있는 것 같습니다. 그래서 당신은 할 수 있다면 다음 (I 구문 혼란을 피하기 위해하여 SerialPort 할당을 변경 한 유의하십시오. 터미네이터가 종료 문자 (들 포함하는 문자열)입니다

 p = new SerialPort(PortName, BaudRate, Prty, DataBits, SBits); 
     p.NewLine = Terminator; 

은 그럼 당신은 SerialPort.ReadLine()을 (사용할 수 있습니다 SerialPort.WriteLine()이 적용되는 경우) 적어도 첫 번째 문제에 도움이 될 수 있습니다.

+0

"NewLine"에 대한 힌트를 읽어 주셔서 감사합니다. TCP에 너무 익숙해졌으며 패킷 생성 및 처리 방법에 익숙했습니다. 방금 "메시지를 보내고"받을 수 있다고 생각했습니다. :) – GONeale

+0

내 NewLine 문자를 볼 수 있듯이 0x03이어야합니다. 실제로는 0x03 + "j"여야합니다. 왜 마지막에 임의의 알파 문자를 인쇄하는지 모르겠지만, 지금은 항상 "j"경향이 있습니다. 이것이 상관 관계가 있는지 나는 모르겠다. 그리고 받아 들인 데이터를 분할하고자하는 문자로 NewLine을 이해해야한다. – GONeale

+0

p.NewLine은 임의의 문자 수의 문자열이 될 수 있습니다. 필자는 "\ n"또는 "\ r \ n"인 디바이스로만 작업을 해왔지만 아무 것도 할 수 없었습니다. 패킷 예에서 첫 번째 줄의 마지막 문자는 무엇입니까? –

3

저는 Win32 직렬 포트 프로그래밍을 많이했지만 .NET에서는 약간의 작업을 수행 했으므로 소금의 알갱이.

내 읽음이 여러 개의 메시지 또는 recei COM 포트를 통해 조각난 응답으로 ved를 사용했는데 어떤 설정이 필요한지 또는이 문제를 해결하기 위해 코드를 어떻게 다르게 작성해야하는지 모릅니다.

다른 사람들이 말했듯이, 이것은 완전히 정상입니다. DCE 측에있는 장비의 유형에 따라 직접 재 포장해야 할 수도 있습니다. 어떤 장비를 연결했는지 모르겠으므로 훨씬 더 말할 수는 없습니다.

더 많은 데이터를 얻을하려면 다음 시도 할 수 있습니다 : 읽을 바이트의 고정 된 수의 동기 I/O를 사용하여 선택 System.Int32 ReceivedBytesThreshold 속성

  • 을 조정하고 지정

    • 보다는를 이벤트 기반 수신

    " 거의 모든주기를 통해 기호를 읽는 것은 입니다. 이것은 내가 설정 한 명령으로 인해 잘못 입력 된 것입니다. 통신 기기의 무언가 또는 이 나를 보내고 있습니까? (하이퍼 터미널 연결 이 문자 지속적으로 전송되지 않는 계시로 나는,하지만 그렇게 을 생각하지 않습니다.) 당신이 라인을 통해 무슨 일이 일어나고 있는지에 대한 궁금하다면

    PortMon from SysInternals 체크 아웃, 무료를 당신이 라인을 통해 데이터를 전송하는 동안 귀하의 COM 포트를 스눕하게 될 것입니다. 기술적 인 것으로 보이지만 실제로는 IRP_MJ_WRITE 및 IRP_MJ_READ 명령을 살펴 봐야합니다. 줄에는 바이트로 된 길이와 와이어를 통해 전송 된 데이터가 표시됩니다. 이것으로 문제가 .NET SerialPort 객체인지 아니면 디바이스가 실제로 "|"를 전송하는지 알 수 있습니다. 줄을 넘어서.

    당신은 내가 각각의 방법에 올바르게 읽고 데이터를 기록하고 확인할 수 있습니다.

    데이터를 수신하는 이벤트 기반 방법에 적합합니다.

  • +0

    정말 대단히 통찰력있는, 특히 PortMon 도구. 그게 내게 어디에서 유래했는지 알려줘야합니다. 지금 수동으로 패킷을 처리하고 있습니다. 제대로 작동하고 있습니다. 포인트 1에 대한 내 게시물을 업데이트 할 것입니다. – GONeale

    관련 문제