소켓에서 새로운 데이터를 모니터링하고 해당 데이터를 처리하는 가장 좋은 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/453609

문제

내 C#.Net 초보자 상태를 용서해 주세요.이것이 명백하고 문서에서 누락된 경우 관련 페이지 또는 샘플 코드에 대한 링크를 제공해 주시면 감사하겠습니다.

저는 Java 애플리케이션에서 TCP 소켓 연결을 허용하는 애플리케이션을 개발 중입니다.(예, 해당 부분에는 Java가 필요합니다.이는 Sun SPOT 장치이고 Java가 유일한 옵션입니다.) Java 앱은 주기적으로 소켓에 새 데이터를 쓰고 내 앱의 작업은 byte[]를 가져와 문자열로 변환하고 데이터를 처리하는 것입니다(업데이트 UI 등) 유사한 C#.NET 앱을 실행하는 다른 컴퓨터로 데이터를 전달할 수도 있습니다.

지금까지 내가 한 일은 다음과 같습니다.현재 앱은 실행 시 소켓을 여는 스레드를 가동합니다.Java 앱이 소켓에 성공적으로 연결되어 작동할 수 있습니다.저는 NetworkStream을 보고 있었습니다. beginRead 방법과 dataAvailable, length, 그리고 CanRead 그러나 일반적으로 약 512바이트이지만 다를 수 있는 데이터 패킷 하나를 읽었을 때 확인하는 방법을 완전히 확신하지 못합니다.

Java 앱이 스트림에 데이터를 쓰거나 데이터 백로그가 있는 경우(Java 앱은 데이터를 다소 빠르게 전달합니다.) 한 번에 하나의 데이터 패킷만 읽고 있는지 어떻게 확인할 수 있습니까?Java 앱 null이 쓰기 시 데이터를 종료하는 경우 도움이 될까요?충분한가?

마지막으로 소켓은 하나의 연결만 수신하지만 오류가 발생하거나 연결이 종료될 때까지 열린 상태를 유지해야 합니다.이 측면을 처리하는 가장 우아한 방법은 무엇입니까?Sun SPOT 베이스 스테이션에서 실행되는 Java 앱의 급속한(거의 실시간) 측면 때문에 각 데이터 패킷을 닫았다가 다시 열면 작동하지 않을 것이라고 생각합니다.지금은 기지국이 종료되면 내 앱이 시끄럽고 고통스럽게 죽습니다.:)

읽어주셔서 감사하고 도움을 주실 수 있습니다.

도움이 되었습니까?

해결책 3

우리가 이 문제를 해결한 방법은 센티널 문자와 고정 너비 필드를 조합하는 것입니다.처음 2바이트는 전체 패킷의 길이 헤더입니다.그런 다음 패킷을 byte[] 버퍼로 ​​읽은 다음 자체 패킷 구조를 사용하여 예를 들어 처음 2바이트가 각각 개별 필드로 해석되고 문자열 필드가 문자로 끝나는 것을 확인합니다. (집에서 득점하는 경우 0x0A).그런 다음 긴 데이터 필드는 8개의 연속 바이트 등을 읽는 방식으로 처리됩니다.우리에게는 꽤 잘 작동하는 것 같지만 소켓의 양쪽 끝을 제어할 수 있고 한쪽 끝만 제어할 수 있는 상황에 대한 솔루션인 것은 분명합니다.이것이 다른 사람에게도 도움이 되기를 바랍니다.

다른 팁

"Java 앱이 스트림에 데이터를 작성하거나 데이터 백 로그가있는 경우 (Java 앱은 데이터를 빨리 전달할 것입니다.) 한 번에 하나의 데이터 패킷 만 읽고 있는지 어떻게 알 수 있습니까?"

어떤 데이터가 어떤 패킷이 끝나는 지에 대한 제어가 있다고 가정하지 않도록주의하십시오. 바이트 데이터를 보내려고하는 경우 { 'H', 'e', 'l', 'l', 'o' } 이 모든 데이터가 단일 패킷으로 전송 될 것이라는 보장은 없습니다. 각 패킷에는 단일 바이트 만 포함 할 수 있으므로 5 개의 다른 이벤트에서 5 바이트를 모두받을 수는 없습니다. 요점은 이런 식으로 패킷에 의존하지 않습니다. 대신, 자신의 메시지 종단 종단을 정의하고 모든 수신 데이터를 어떤 종류의 바이트 버퍼에 버리고이 터미네이터가있는 경우 다른 기능을 수행해야합니다. 그렇다면 해당 터미네이터를 읽으십시오. 예를 들어 다음 데이터를 포함하는 Java 응용 프로그램의 각각의 보내기 메소드를 두 번 호출하십시오.

{ 'H', 'e', 'l', 'l', 'o', '\0' }
{ 'W', 'o', 'r', 'l', 'd', '\0' }

데이터를 받기 위해 응용 프로그램을 준비 해야하는 방법은 다음과 같습니다.

Server receives { 'H', 'e', 'l' }
Data stored in byte buffer { 'H', 'e', 'l' }
Check byte buffer for message terminator '\0'. None found. Buffer unchanged, no message processed.
Server receives { 'l', 'o', '\0', 'W' }
Data stored in byte buffer { 'H', 'e', 'l', 'l', 'o', '\0', 'W' }
Check byte buffer for message terminator '\0'. 1 found, extracted message { 'H', 'e', 'l', 'l', 'o' } and buffer updated { 'W' }

그래서 그것은 원래 질문에 대한 답이 아니었지만 올바른 방향을 추진해야한다고 생각합니다.

당신이 실행할 수있는 한 가지는 메시지 터미네이터 대신 데이터가 될 수없는 문자가 없다는 것입니다. 예를 들어, 많은 파일에는 데이터가 포함되어 있으므로 메시지 감지를 망칠 수 있습니다. 일반적으로 처리되는 방법은 프로토콜을위한 헤더 사양을 작성하고 헤더를 기대하는지 여부 ( 0을 찾는 경우 메시지의 끝을 나타냅니다) 또는 일정량의 시간을 기다리는 것인지 감지하는 것입니다. 데이터 (마지막 헤더로 지정할 수있는 데이터)이 이해가되지 않고이 기술을 사용해야 할 수도 있다고 생각하면 저에게 알려 주시면이 답변에 추가하겠습니다.

스트리밍 데이터를 읽을 때는 읽기를 중지하고 정보를 처리 할시기를 결정하기 위해 Sentinel/종료 문자 또는 알려진 데이터 크기가 필요합니다. 널 캐릭터 또는 신약이 일반적입니다. 다른 기술은 본체의 길이를 지정하는 고정 크기 헤더를 사용하는 것입니다.

소켓은 닫을 때까지 열려 있거나 다른 쪽이 끝날 때까지 열려 있습니다.이 경우 소켓에서 읽는 동안 오류가 발생하여 손잡이가 손상됩니다. 네트워크 스트림은 읽기 또는 쓰기 작업 중에 소켓이 원격 쪽에서 닫히면 IOException을 던졌습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top