none
TcpListener e TcpClient non funzionano sui tablet. RRS feed

  • Domanda

  • Signori Buona giornata.

    Ho sviluppato per dei tablet un applicativo. Fra le varie routine contiene la trasmissione dei dati del dataset in formato .xml al computer centrale. Provato, riprovato e ottimizzato fra un computer fisso e un portatile tutto funziona.

    Istallato sui tablet che girano con windows 10 (come le altre due macchine citate) la trasmissione non avviene.

    Il tablet al file .xml aggiunge degli spazi vuoti e caratteri inesistenti. Per cui il sever, che conosce la dimensione del file, al raggiungimento di questa dimensione chiude l'ascolto, ma il client non ha finito.

    I dati in attesa sono:

     <Bolle>
        <NumeroBolla>195_L-4/2016</NumeroBolla>
        <DataBolla>2016-07-13T00:00:00+02:00</DataBolla>
        <Targa>DH 296 ST</Targa>
        <Città>MONTE</Città>
      </Bolle>
      <CLIENTI>
        <idCliente>6</idCliente>
        <Società>SANCIO PANCIA</Società>
        <Cognome />
        <Nome />
        <Indirizzo>VIA MONFALCONE NR. 83</Indirizzo>
        <CAP>7800</CAP>
        <Comune>MANFREDI</Comune>
        <PROVINCIA>XH</PROVINCIA>
        <PartitaIVA>01627810000</PartitaIVA>
        <StringaRecapiti>10 1 2 3 4 5</StringaRecapiti>
        <StringaTestiRecapiti xml:space="preserve">     </StringaTestiRecapiti>

    Arrivano:

    <Bolle>
        <NumeroBolla>195_L-4/2016</NumeroBolla>
        <DataBolla>2016-07-13T00:00:00+02:00</DataBolla>
        <Targa>DH 296 ST</Targa>
        <Città>MONTE</Città>
      </Bolle>
      <CLIENTI>
        <idCliente>6</idCliente>
        <Società>SANCIO PANCIA</Società>
        <Cognome />
        <Nome />
        <Indirizzo>VIA MONFALCONE NR. 83</Indirizzo>
        <CAP>7800</CAP>
        <Comune>MANFREDI</Comune>
        <PROVINCIA>XH</PROVINCIA>
        <PartitaIVA>01627810000</PartitaIVA>
        <StringaRecapiti>10 1 2 3 4 5</StringaRecapiti>
        <StringaTestiRecapiti xml:space="preserve">     </StringaTestiRecapiti>

    Risultano errati i campi città e società. La stringa recapiti a causa delle A accentate risulta più lunga e falsa la dimenzione del file trasmesso.

    Provato il trasferimento con software di terze parti. Tutto va per il meglio.

    Ovviamente non ho la pretesa che anche il mio dovesse funzionare, ma la speranza dopo tante prove c'è l'avevo.

    Tutte le machine funzionano con Windows 10. Programma sviluppato con vb 2010 framwork 4.

    Vediamo: la corrente ci sta, l'acqua l'ho aperta, il detersivo l'ho messo, i panni sporchi ci sono, l'oblò è chiuso... ma perché questa lavatrice non parte?

    Grazie

    Celestino

    giovedì 8 giugno 2017 09:59

Risposte

  • Non c'entra niente il S.O.

    Dipende tutto dalla serializzazione Xml dei caratteri Unicode (caratteri accentati) di cui non ne hai il controllo utilizzando i DataSet. Per ovviare a questo dovresti leggere l'Xml, convertirlo in un Array ASCII e trasmetterlo come Array di Byte... in altri termini una bella rogna.... :)

    Il metodo che usi per trasmettere i dati, però mi sembra un po' arcaico... perché non usi WCF hostato sulle applicazioni? Rimuovi tutti i problemi di serializzazione dei dati e usi le interfacce che ti rappresentano le classi dati che vuoi scambiare, così sei sicuro che le classi vengono trasmesse per intero, non devi gestire la comunicazione perché ci pensa WCF e tanto altro... Qua trovi un esempio molto semplice da cui partire:

    https://msdn.microsoft.com/it-it/library/ms731758%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

    HTH


    Alberto De Luca [MVP - Visual Studio and Development Technologies] www.dotnetwork.it

    venerdì 9 giugno 2017 11:54

Tutte le risposte

  • I caratteri accentati e i caratteri speciali devi trasmetterli come una sequenza di escape, altrimenti non vengono interpretati correttamente. Cosa utilizzi per serializzare l'XML?

    Alberto De Luca [MVP - Visual Studio and Development Technologies] www.dotnetwork.it

    giovedì 8 giugno 2017 15:49
  • Salve,

    utilizzo: 

    Ds.ReadXml(archivioOdierno) e Ds.WriteXml(archivioOdierno)

    dove in archivioOdierno c'è il path, il nome e tutto il necessario.

    però credo che non sia importante questo perché il programma funzionano se ci sono due macchine "Capaci", un pc-portatile e uno fisso. Il mio dubbio è che sul tablet il sistema operativo sia, per così dire, "Light" per cui alcune funzioni o mancano o non sono implementate bene.

    D'altra parte, a parte i campi del database, non posso sapere se l'utente utilizza l'indicativo futuro  nel campo note o da qualche altra parte a sua disposizione.

    Inoltre nella <StringaRecapiti> le  sono diverse da quelli dei campi di <Società> e <Città>. nei campi del database vengono sostituite le à, ma nella <StringaRecapiti> sono semplicemente degli spazi.

    Grazie per l'attenzione dedicatomi.

    Celestino

    venerdì 9 giugno 2017 11:23
  • Non c'entra niente il S.O.

    Dipende tutto dalla serializzazione Xml dei caratteri Unicode (caratteri accentati) di cui non ne hai il controllo utilizzando i DataSet. Per ovviare a questo dovresti leggere l'Xml, convertirlo in un Array ASCII e trasmetterlo come Array di Byte... in altri termini una bella rogna.... :)

    Il metodo che usi per trasmettere i dati, però mi sembra un po' arcaico... perché non usi WCF hostato sulle applicazioni? Rimuovi tutti i problemi di serializzazione dei dati e usi le interfacce che ti rappresentano le classi dati che vuoi scambiare, così sei sicuro che le classi vengono trasmesse per intero, non devi gestire la comunicazione perché ci pensa WCF e tanto altro... Qua trovi un esempio molto semplice da cui partire:

    https://msdn.microsoft.com/it-it/library/ms731758%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

    HTH


    Alberto De Luca [MVP - Visual Studio and Development Technologies] www.dotnetwork.it

    venerdì 9 giugno 2017 11:54
  • Ciao

    nella fase di invio li trasformo in array di byte e uso:

        'Invia un messaggio su uno stream di rete
        Private Sub Send(ByVal Msg As String, ByVal Stream As NetworkStream)
            'Se sì, può scrivere
            If Stream.CanWrite Then
                'Converte il messaggio in binario
                Dim Bytes() As Byte = ASCII.GetBytes(Msg)

                'E lo scrive sul network stream
                Stream.Write(Bytes, 0, Bytes.Length)
            End If
        End Sub

    però hai ragione perché rivedendo il codice del BackGrounWorker  trovo:

     Dim FileName As String = e.Argument
            'Crea un nuovo lettore del file a basso livello, così
            'da poter ottenere bytes di informazione anziché caratteri

            'come nello StreamReader
            Dim Reader As New IO.FileStream(FileName, IO.FileMode.Open)

            'Calcola la grandezza del file, per poter poi tenere
            'l'utente al corrente della percentuale di completamento

    Dim Size As Int64 = FileLen(FileName)

            'Un blocco di bytes da 4096 posti. Il file viene spedito in
            '"pacchettini" per evitare di sovraccaricare la connessione
            Dim Bytes(4095) As Byte

            'Se il file è più grande di 4KiB, lo divide
            'in blocchi di dati da 4096 bytes
            Try

                If Size > 4096 Then
                    For Block As Int64 = 0 To Size Step 4096
                        'Se i bytes rimanenti sono più di 4096,
                        'ne legge un blocco intero
                        If Size - Block >= 4096 Then
                            Reader.Read(Bytes, 0, 4096)  'Il metodo READ dovrebbe trasformare i codici in ASCII in Array di Byte? Altrimenti l'errore è qui.
                        Else
                            'Altrimenti un blocco più piccolo
                            Reader.Read(Bytes, 0, Size - Block)
                        End If
                        'Scrive i dati prelevati sullo stream di rete,
                        'inviandoli così al server
                        NetFile.Write(Bytes, 0, 4096)
                        'Riporta la percentuale all'utente
                        bgSendFile.ReportProgress(Block * 100 / Size)
                        'Smette per 30ms, così da dare tempo dal
                        'server di poter processare i pacchetti uno per
                        'uno
                        Threading.Thread.Sleep(30)
                    Next

                Else
                    'Se il file è minore di 4KiB, lo invia tutto
                    'direttamente dal server
                    Reader.Read(Bytes, 0, Size)
                    NetFile.Write(Bytes, 0, Size)
                End If

            Per il futuro sicuramente terrò conto dei tuoi consigli, ma questo era un programma già fatto per cui lo tenevo così com'è.

    Grazie per tutto

    Celestino

      

    venerdì 9 giugno 2017 13:25