sockets / data ontvangen + foutcontrole op uitvallen netwerk, ...

  • Onderwerp starter Onderwerp starter mmy
  • Startdatum Startdatum
Status
Niet open voor verdere reacties.

mmy

Gebruiker
Lid geworden
17 okt 2007
Berichten
11
Een server stuurt data uit op een bepaalde poort. Het is de bedoeling dat ik met mijn pc gewoon naar het IP adres van deze server luister, op die poort. Zelf moet ik voorlopig geen data kunnen sturen.

Mbv sockets.net ben ik tot onderstaande code geraakt.
Code:
Imports System.Net 
Imports System.Net.Sockets 

Public Class Form1 

Private ClientSocket As Socket 
 'om bytes om te zetten naar een string & omgekeerd (voor versturen & ontvangen) 
Private ASCII As New System.Text.ASCIIEncoding()                    

Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click 

    'naam van de server omzetten naar IP adres 
    Dim Addr As IPAddress 
    Addr = Dns.GetHostEntry(txtAddress.Text).AddressList(0) 

    'IP Endpoint maken (= de server waarmee we willen connecteren) 
    Dim EP As New IPEndPoint(Addr, CInt(txtPort.Text)) 

    'socket aanmaken 
    ClientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) 

    'connectie maken -> dit gaan we asynchroon (callback) doen (in de functie ConnectCallback) 
    ClientSocket.BeginConnect(EP, AddressOf ConnectCallback, Nothing)                            

End Sub 

Private Sub ConnectCallback(ByVal ar As IAsyncResult) 
    ClientSocket.EndConnect(ar) 
    Dim bytes(4095) As Byte 
    ClientSocket.BeginReceive(bytes, 0, bytes.Length, SocketFlags.None, AddressOf ReceiveCallback, bytes) 
end sub 

Private Sub ReceiveCallback(ByVal ar As IAsyncResult) 
    'deze functie wordt uitgevoerd op de achtergrond als er data ontvangen wordt 

    'hierin gaan we de ontvangen data opslaan 
    Dim bytes() As Byte                                              
    bytes = CType(ar.AsyncState, Byte()) 

    'onthouden i/e variabele hoeveel bytes ontvangen zijn 
    Dim numbytes As Int32 = ClientSocket.EndReceive(ar) 

    If numbytes = 0 Then                                         'indien aantal ontvangen bytes = 0 
       ClientSocket.Shutdown(SocketShutdown.Both) 'connectie sluiten 
       ClientSocket.Close() 
       'DisConnectedUI is de sub waarmee we de info op het main form aanpassen 
       Dim dlg As New NoParamsDelegate(AddressOf DisconnectedUI)    
       Me.Invoke(dlg)                                               
    Else                                                                 'meer dan 0 bytes ontvangen... 
       Dim Recv As String                                        'variabele om de data in te plaatsen 
       Recv = ASCII.GetString(bytes, 0, numbytes)    'in bytes staat de ontvangen data -> dit omzetten naar een string 
       Array.Clear(bytes, 0, bytes.Length) 
       'tonen in main form 
       Dim dlg As New OneStringDelegate(AddressOf DisplayReceivedData)  
       Dim args() As Object = {Recv} 
       Me.Invoke(dlg, args) 

       'data terug ontvangen 
       ClientSocket.BeginReceive(bytes, 0, bytes.Length, SocketFlags.None, AddressOf ReceiveCallback, bytes) 

    End If 
End Sub 

Private Sub DisplayReceivedData(ByVal data As String) 
    'deze sub wordt uitgevoerd als er data ontvangen is (deze sub wordt geactiveerd via  
    txtOntvangen.Text = data 
End Sub 

Private Delegate Sub OneStringDelegate(ByVal data As String) 
Private Delegate Sub NoParamsDelegate() 

End Class

Met bovenstaande code heb ik enkele problemen:
1) is er een mogelijkheid om te controleren of het netwerk nog beschikbaar is, de server nog beschikbaar is, ... Of moet ik dan gewoon gebruik maken van try - catch?
2) als ik connectie wil maken met de mail server, dan wordt deze connectie onmiddellijk tot stand gebracht. Wil ik met een ander toestel (bv. telefooncentrale) connectie maken, dan duurt het een 20 tal seconden. De connectie is daarna wel in orde. Met winsock in vb6 ging dit vrijwel onmiddellijk.

Als 2de voorbeeld heb ik deze code...
Code:
Imports System.Net.Sockets 
Imports System.Text 

Public Class Form1 

Private ASCII As New System.Text.ASCIIEncoding 
Private MyClient As TcpClient 
Private mydata(4095) As Byte 

Private Sub btnMaakConnectie_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMaakConnectie.Click 
    Try 
       'connectie opzetten indien IP & poort beschikbaar zijn 
       MyClient = New TcpClient(txtIP.Text, txtPoort.Text) 
       'data uitlezen (asynchroon) 
       MyClient.GetStream.BeginRead(mydata, 0, 4095, AddressOf DataUitlezen, Nothing) 
    Catch ex As Exception 
        ....     
    End Try 
End Sub 

Private Sub DataUitlezen(ByVal ar As IAsyncResult) 
    'asynchrone callback functie om data uit te lezen 
    Dim ingelezen_data_lengte As Integer                         
    Try 
       ingelezen_data_lengte = MyClient.GetStream.EndRead(ar)   
       If ingelezen_data_lengte < 1 Then                        
           txtInfo.AppendText("Disconnected" & vbCrLf) 
           Exit Sub 
       End If 

       'data in bytes omzetten naar een string 
       Dim tekst As String 
       tekst = ASCII.GetString(mydata, 0, ingelezen_data_lengte) 
       '.... 
       'data nogmaals uitlezen... 
       MyClient.GetStream.BeginRead(mydata, 0, 4095, AddressOf DataUitlezen, Nothing) 

    Catch ex As Exception                                     
       MessageBox.Show("er kan geen data meer uitgelezen worden - fout = " & vbCrLf & ex.Message) 
    End Try 
End Sub 

Private Sub btnConnectieVerbreken_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnectieVerbreken.Click 
    Try 
      MyClient.Close() 
      MyClient = Nothing 
    Catch ex As Exception 
      Exit Sub 
    End Try 
End Sub 
End Class

1) deze maakt wel onmiddellijk een connectie met de telefooncentrale. Mbv het try - catch blok controleer ik nu steeds of er nog een connectie is of niet.
2) Als ik op btnConnectieVerbreken klik krijg ik wel een warning: "A first chance exception of type 'System.NullReferenceException' occurred in ....". Onmiddellijk daarna krijg ik nog de error uit het catch-blok van de sub DataUitlezen (deze kan ik wel vermijden door met een "vlag" te controleren of er nog data uitgelezen moet worden).

Enige probleem ook met deze code...Indien er geen netwerkconnectie beschikbaar is, of de server is onbekend -> wanneer ik de connectie wil opzetten bevreist de user interface tot na de time out (ongeveer 20sec).

Heeft iemand meer info? Mbv de voorbeelden die ik vind op het net geraak ik jammer genoeg niet verder...
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan