2015-07-30 14 views
6

Ho un modulo che crea un oggetto UDP, nella classe UDP viene creato un UDPClient e i dati ricevuti vengono eseguiti nel metodo BeginReceive utilizzando EndReceive.Impossibile aggiungere alla stringa ricevuta nel listener UDP C#

Quando stampo la stringa dei dati ricevuti, dopo aver convertito il byte [], nella console dal metodo beginreceive, con il testo aggiunto, solo i dati ricevuti non stampano il testo aggiunto.

Quindi sembra che i dati ricevuti siano incompleti.

Quando la stringa viene stampata, la NewLine e l'aggiunta "completata" non vengono visualizzate.

Qualsiasi aiuto sarebbe fantastico !!

Grazie

class Udp 
{ 
    public EventHandler _dataReceived; 

    public Udp() 
    { 

     int receiverPort = 1248; 
     UdpClient receiver = new UdpClient(receiverPort); 

     string discovery = "<?xml version=\"1.0\"?><ServiceQuery></ServiceQuery>"; 

     receiver.BeginReceive(new AsyncCallback(DataReceived), receiver); 

     IPEndPoint end = new IPEndPoint(IPAddress.Broadcast, 1248); 
     receiver.Send(Encoding.ASCII.GetBytes(discovery + "\0"), discovery.Length + 1, end); 
} 

private void DataReceived(IAsyncResult ar) 
{ 
    UdpClient c = (UdpClient)ar.AsyncState; 
    IPEndPoint receivedIpEndPoint = new IPEndPoint(IPAddress.Any, 1248); 

    Byte[] receivedBytes = c.EndReceive(ar, ref receivedIpEndPoint); 

    string receivedText = ASCIIEncoding.ASCII.GetString(receivedBytes); 

    Console.WriteLine("\n"); 

    if(_dataReceived != null) 
    { 
     Console.Write(receivedIpEndPoint + ": " + receivedText + Environment.NewLine + "done"); 
     _dataReceived(receivedText, new EventArgs()); 
    } 

    c.BeginReceive(new AsyncCallback(DataReceived), c); 
} 

    }  
+0

almeno un campione banale con il codice sorgente necessario. – Jichao

+0

Ho modificato qualche codice sorgente, come ho detto sopra. Newline e "done" non vengono stampati –

+0

Hai provato a utilizzare la classe Stringbuilder anziché la stringa? –

risposta

4

La Repro più semplice che posso pensare per questo problema è di questo codice:

private void button1_Click(object sender, EventArgs e) { 
     Byte[] receivedBytes = new byte[] { 0x48, 0x65, 0x6c, 0x00, 0x6c, 0x6f }; 
     string receivedText = Encoding.ASCII.GetString(receivedBytes); 
     Console.Write(receivedText + ", you won't see this"); 
    } 

uscita dopo aver fatto clic sul pulsante più volte:

HelHelHelHel 

Sicuramente ora riconosci la pillola velenosa nel receivedBytes array, è la presenza del byte 0x00 che causa l'interruzione della stringa di output. Niente oltre quel byte lo rende nella finestra di output di Visual Studio.

Spiegare questo comportamento richiede un'immersione profonda di come funziona Console.Write() in un'applicazione Winforms e come è in grado di generare output, anche se il programma non ha console. È una storia prolissa che non è in grado di intrattenere nessuno, quindi scommetto sulla versione breve. Con l'opzione debugger di Visual Studio Hosting Process abilitata, Console.Write() è equivalente a Debug.Write(). L'output di debug viene intercettato dalla classe DefaultTraceListener, che richiama il numero OutputDebugString() per visualizzare il testo nella finestra di traccia del debugger. Queste funzioni winapi richiedono stringhe C, una stringa C è terminata da zero per indicare la fine della stringa.

Ci sono diversi modi per risolvere questo, modo del programmatore è quello di convertire il byte [] contenuti array esadecimale:

Byte[] receivedBytes = new byte[] { 0x48, 0x65, 0x6c, 0x00, 0x6c, 0x6f }; 
    string receivedText = BitConverter.ToString(receivedBytes); 
    Console.WriteLine(receivedText + ", you see this"); 

uscita:

48-65-6C-00-6C-6F, you see this 
    48-65-6C-00-6C-6F, you see this 
    48-65-6C-00-6C-6F, you see this 

Oppure si potrebbe desiderare di prendere una guarda meglio i dati che trasmetti, assicurandoti che sia effettivamente un testo stampabile che può essere convertito correttamente con Encoding.ASCII