문제

내 문제는 로컬 LAN 네트워크를 통해 연속적인 데이터 스트림을 스트리밍할 때 때때로 임의의 바이트가 프로세스에서 손실된다는 것입니다.

현재 코드는 LAN을 통해 약 1027바이트를 초당 약 40회 스트리밍하도록 설정되어 있으며 때로는 (매우 드물지만) 하나 이상의 바이트가 손실됩니다.

나를 당황하게 만드는 것은 실제 바이트가 "손실"되지 않고 원래 데이터에 관계없이 0으로 설정된다는 것입니다.(저는 TCP를 사용하고 있습니다)

보내는 코드는 다음과 같습니다.

    public void Send(byte[] data)
    {
        if (!server)
        {
            if (CheckConnection(serv))
            {
                serv.Send(BitConverter.GetBytes(data.Length));
                serv.Receive(new byte[1]);
                serv.Send(data);
                serv.Receive(new byte[1]);
            }
        }
    }

수신 코드는 다음과 같습니다.

    public byte[] Receive()
    {
        if (!server)
        {
            if (CheckConnection(serv))
            {
                byte[] TMP = new byte[4];
                serv.Receive(TMP);
                TMP = new byte[BitConverter.ToInt32(TMP, 0)];
                serv.Send(new byte[1]);
                serv.Receive(TMP);
                serv.Send(new byte[1]);
                return TMP;
            }
            else return null;
        }
        else return null;
    }

빈 바이트를 보내고 받는 것은 시스템을 동기화 상태로 유지하기 위한 것입니다.개인적으로 문제는 시스템의 수신 측에 있다고 생각합니다.하지만 그 제트기를 증명할 수는 없었습니다.

도움이 되었습니까?

해결책

당신이 준다는 것만으로도 Receive(TMP) 4바이트 배열이 해당 배열을 4바이트로 채운다는 의미는 아닙니다.수신 호출은 다음 사이 어느 곳에나 들어갈 수 있습니다. 1 그리고 TMP.Length 바이트를 배열에 넣습니다.반환된 내용을 확인해야 합니다. int 채워져 있는 배열의 바이트 수를 확인합니다.

네트워크 연결은 메시지 기반이 아닌 스트림 기반입니다.회선에 넣은 모든 바이트는 큰 대기열에 연결되고 사용 가능해지면 반대편에서 읽혀집니다.따라서 두 배열을 보낸 경우 1,1,1,1 그리고 2,2,2,2 수신 측에서 전화하는 것이 전적으로 가능합니다. Receive 4바이트 배열로 세 번 실행하고

  • 1,1,0,0 (반품을 받다 2)
  • 1,1,2,2 (반품을 받다 4)
  • 2,2,0,0 (반품을 받다 2)

따라서 당신이 해야 할 일은 당신이 돌려받은 가치를 살펴보는 것입니다. Receive 바이트 배열이 가득 찰 때까지 계속 반복하십시오.

byte[] TMP = new byte[4];

//loop till all 4 bytes are read
int offset = 0;
while(offset < TMP.Length)
{
    offset += serv.Receive(TMP, offset, TMP.Length - offset, SocketFlags.None);
}
TMP = new byte[BitConverter.ToInt32(TMP, 0)];

//I don't understand why you are doing this, it is not necessary.
serv.Send(new byte[1]); 

//Reset the offset then loop till TMP.Length bytes are read.
offset = 0;
while(offset < TMP.Length)
{
    offset += serv.Receive(TMP, offset, TMP.Length - offset, SocketFlags.None);
}

//I don't understand why you are doing this, it is not necessary.
serv.Send(new byte[1]);

return TMP;

마지막으로 "네트워크 스트림이 당신을 혼란스럽게 한다"고 말씀하셨습니다. 위의 문제가 당신을 혼란스럽게 하는 것 중 하나일 것이라고 장담합니다. 더 낮은 수준으로 이동해도 이러한 복잡성이 제거되지는 않습니다.이러한 복잡한 부분을 없애서 처리할 필요가 없도록 하려면 라이브러리 내부에서 해당 부분을 처리해 주는 타사 라이브러리를 사용해야 합니다.

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