Domanda

Il mio problema è che quando sto streamando un flusso continuo di dati su una rete LAN locale a volte i byte casuali vengono persi nel processo.

Come è in questo momento il codice è impostato per flussi circa 1027 byte o così ~ 40 volte un secondo su una LAN e talvolta (molto raro) uno o più dei byte sono persi.

La cosa che mi sfoglia è che il byte effettivo non è "perso" è solo impostato su 0 indipendentemente dai dati originali.(Sto usando TCP a proposito)

Ecco il codice di invio:

    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]);
            }
        }
    }
.

e il codice ricevente:

    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;
    }
.

L'invio e la ricezione dei byte vuoti sono solo per mantenere il sistema in sincronizzazione. Personalmente penso che il problema sia sul lato ricevente del sistema.non sono stato in grado di dimostrare quel jet però.

È stato utile?

Soluzione

Solo perché dai Receive(TMP) un array di 4 byte non significa che riempirà quella matrice con 4 byte. La chiamata di ricezione è autorizzata a inserire ovunque tra 1 e byte TMP.Length nell'array. È necessario controllare il int restituito per vedere quanti byte dell'array si riempiono.

Le connessioni di rete sono basate su flusso non basate sul messaggio. Qualsiasi byte che hai indossato al filo si è concatenato in una grande coda e si legge dall'altra parte mentre diventa disponibile. Quindi, se hai inviato i due array 1,1,1,1 e 2,2,2,2 è del tutto possibile che sul lato ricevente chiami Receive tre volte con un array a 4 byte e ottenere

    .
  • 1,1,0,0 (ricevi 2 restituito)
  • 1,1,2,2 (ricevi 4 restituito)
  • 2,2,0,0 (ricevi 2 restituito)

Allora, quindi cosa devi fare è guardare i valori che hai tornato da Receive e tenere il looping fino a quando il tuo array di byte è pieno.

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;
.

Infine hai detto "Il flusso di rete ti confonde", sono disposto a scommettere il problema di cui sopra è una delle cose che ti ha confuso, andare a un livello inferiore non rimuovere quelle complessità. Se vuoi che queste parti complesse sono andate così che non devi gestirle, dovrai utilizzare una biblioteca di terze parti che lo gestirà per te all'interno della libreria.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top