Avatar billede jobless Nybegynder
29. januar 2010 - 13:07 Der er 14 kommentarer og
1 løsning

Hjælp til netværks-kommunikation

Hej.

Jeg fifler med en client/server ting, baseret på denne super gode guide: http://www.eksperten.dk/guide/515

Mine applikationer virker som ønsket med brug af binarywrite/binaryread.

Som det er bygget op pt. (vha. guiden), sender client en anmodning, og server svarer.

Dette er helt fint, men jeg har behov for at serveren kan initiere kommunikationen på et senere tidspunkt, for at broadcaste noget info (via binaryread/write som i guiden).

Hvordan tilretter jeg vb.net eksemplerne til at kunne gøre dette ?

Jeg har forsøgt mig med at bygge begge class'er sammen, og anvende to porte, men desværre uden held.
Avatar billede arne_v Ekspert
29. januar 2010 - 15:45 #1
Hvis serveren skal initiere kommunikation, saa er det nemmeste at starte en lytte traad paa client.
Avatar billede jobless Nybegynder
29. januar 2010 - 16:01 #2
Kan du give mig nogle hints til hvordan dette gøres rigtigt, eller endnu bedre; links til eksempler ?
Avatar billede arne_v Ekspert
29. januar 2010 - 16:53 #3
Grundliggende skal client ssa fungere meget ligesom server. Altsaa med en traad som lytter efter noget fra server og processer dette.

Hvis det konsekvent er server->client, saa er det bare saadan.

Hvis det er baade server->client og client->server vil jeg anbefale 2 socket forbindelser - en til hver vej.

Jeg kan evt. bixe noget kode senere.
Avatar billede jobless Nybegynder
29. januar 2010 - 17:28 #4
Mit ønske er, at der kan initieres begge veje, og at den ikke-initierende side svarer på en anmodning. Samtidigt har jeg behov for at kunne sende object'er, som der vises i guiden.

Et eksempel jeg har makket noget med er dette: http://www.vbforums.com/showthread.php?s=8ec5b59e1c9621a5550867aec6a14d3d&t=502795

Det kan faktisk den modsatte del af ovennævnte guide, altså initiere fra begge ender, men jeg kan ikke finde ud af at få det til at sende binært.

Hvis du vil bixe noget sammen, vil jeg være ovenud lykkelig, meget gerne i forlængelse af din glimrende guide.
Avatar billede arne_v Ekspert
29. januar 2010 - 17:39 #5
Sende og modtage objekter kraever ikke meget kode:

            Dim bf As BinaryFormatter = New BinaryFormatter()
            bf.Serialize(dinstream, anyserializableobject)

og:

            Dim bf As BinaryFormatter = New BinaryFormatter()
            Dim o As enklasse = CType(bf.Deserialize(dinstream), enklasse)
Avatar billede arne_v Ekspert
29. januar 2010 - 17:40 #6
Jeg proever at bixe et eksempel i aften eller imorgen.

(kl. er kun 11:40 her, saa aften er ikke snart !)
Avatar billede jobless Nybegynder
29. januar 2010 - 18:51 #7
Ok, jeg glæder mig allerede til at se det du får strikket sammen.

Min mål er, at server-delen til skal kunne køre som en service, alternativt en consol application uden user-interface.

Jeg kan rigtigt godt li den måde det er lavet i guiden, alså at man i streamen sender (CONST byte) hvilken funktion man ønsker at kalde.

Er der begrænsninger for hvor meget man kan sende på engang, jeg har behov for at sende f.eks. 3 integers og 5 strings på engang (de udgør værdierne for en datarow), og jeg har enkelte gange behov for at sende 100 datarows, hvis dette er muligt ?
Avatar billede jobless Nybegynder
30. januar 2010 - 07:25 #8
hov, glemte lige at spørge: du er da længere væk end Læsø, med den tidsforskydning, ikke ?
Avatar billede jobless Nybegynder
30. januar 2010 - 17:40 #9
Tror jeg er ved at have hittet den, men har et enkelt problem.

Hvordan sender custom object's vha binarywrite/binaryread, har fiflet lidt med noget serialization, men kan ikke få det til at virke.

Kunne du evt. skrive nogle få linier som tillæg til guiden, så jeg kan semde et custom object ?
Avatar billede arne_v Ekspert
02. februar 2010 - 03:58 #10
Jeg bryggede lige videre på et gammelt client-server eksempel jeg havde.

Server:

Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading

Public Class ChatMain
    Public Shared Sub Main(args As String())
        Dim srv As New Server()
        srv.Run()
    End Sub
End Class

Public Class Server
    Private allclients As List(Of ClientHandler)
    Public Sub Run()
        allclients = New List(Of ClientHandler)()
        Dim server As New TcpListener(IPAddress.Any, 50000)
        server.Start()
        While True
            Dim client As TcpClient = server.AcceptTcpClient()
            Dim ch As New ClientHandler(client, Me)
            allclients.Add(ch)
            Dim t As Thread = New Thread(AddressOf ch.Run)
            t.Start()
        End While
    End Sub
    Public Sub SendAll(msg As String)
        For Each ch As ClientHandler In allclients
            ch.Send(msg)
        Next
    End Sub
    Public Sub SendOne(msg As String, address As String)
        For Each ch As ClientHandler In allclients
            If ch.Remote.IndexOf(address) = 0 Then
                ch.Send(msg)
            End If
        Next
    End Sub
    Public Sub Remove(ch As ClientHandler)
        allclients.Remove(ch)
    End Sub
End Class

Public Class ClientHandler
    Private m_remote As String
    Private rdr As StreamReader
    Private wrt As StreamWriter
    Private srv As Server
    Public Sub New(cli As TcpClient, srv As Server)
        m_remote = cli.Client.RemoteEndPoint.ToString()
        rdr = New StreamReader(cli.GetStream())
        wrt = New StreamWriter(cli.GetStream())
        Me.srv = srv
    End Sub
    Public Sub Run()
        While True
            Dim line As String = rdr.ReadLine()
            Dim parts As String() = line.Split(" ".ToCharArray())
            Dim cmd As String = parts(0)
            If cmd = "SEND" Then
                Dim address As String = parts(1)
                If address = "*" Then
                    srv.SendAll(line.Substring(cmd.Length + address.Length + 2))
                Else
                    srv.SendOne(line.Substring(cmd.Length + address.Length + 2), address)
                End If
            ElseIf cmd = "EXIT" Then
                srv.Remove(Me)
                Return
            End If
        End While
    End Sub
    Public Sub Send(msg As String)
        SyncLock wrt
            wrt.WriteLine(msg)
            wrt.Flush()
        End SyncLock
    End Sub
    Public ReadOnly Property Remote() As String
        Get
            Return m_remote
        End Get
    End Property
End Class

client:

Imports System
Imports System.IO
Imports System.Net.Sockets
Imports System.Threading

Public Class ChatClient
    Public Shared Sub Main(args As String())
        Dim client As New TcpClient("localhost", 50000)
        Dim wrt As New StreamWriter(client.GetStream())
        Dim t As Thread = New Thread(AddressOf (New Reader(client)).Run)
        t.Start()
        Dim line As String
        line = Console.ReadLine()
        While line IsNot Nothing
            wrt.WriteLine("SEND " & line)
            wrt.Flush()
            line = Console.ReadLine()
        End While
        wrt.WriteLine("EXIT")
        wrt.Flush()
        wrt.Close()
        client.Close()
    End Sub
End Class

Public Class Reader
    Private rdr As StreamReader
    Public Sub New(cli As TcpClient)
        rdr = New StreamReader(cli.GetStream())
    End Sub
    Public Sub Run()
        Try
            Dim line As String
            line = rdr.ReadLine()
            While line IsNot Nothing
                Console.WriteLine(line)
                line = rdr.ReadLine()
            End While
        Catch generatedExceptionName As Exception
            ' nothing
        End Try
    End Sub
End Class
Avatar billede arne_v Ekspert
02. februar 2010 - 03:59 #11
USA's østkyst
Avatar billede arne_v Ekspert
02. februar 2010 - 04:02 #12
Et eksempel med binær serialisering:

Imports System
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.Collections.Generic

Namespace E
    Public Class Ser(Of T)
        Public Shared Function Object2ByteArray(o As T) As Byte()
            Dim ms As New MemoryStream()
            Dim bf As New BinaryFormatter()
            bf.Serialize(ms, o)
            Return ms.ToArray()
        End Function
        Public Shared Function Object2String(o As T) As String
            Return Convert.ToBase64String(Object2ByteArray(o))
        End Function
        Public Shared Function ByteArray2Object(b As Byte()) As T
            Dim ms As New MemoryStream(b)
            Dim bf As New BinaryFormatter()
            ms.Position = 0
            Return DirectCast(bf.Deserialize(ms), T)
        End Function
        Public Shared Function String2Object(s As String) As T
            Return ByteArray2Object(Convert.FromBase64String(s))
        End Function
    End Class
    Public Class MainClass
        Public Shared Sub Main(args As String())
            Dim dt1 As DateTime = DateTime.Now
            Console.WriteLine(dt1)
            Dim dt2 As DateTime = Ser(Of DateTime).String2Object(Ser(Of DateTime).Object2String(dt1))
            Console.WriteLine(dt2)
            Dim lst1 As New List(Of String)()
            lst1.Add("A")
            lst1.Add("BB")
            lst1.Add("CCC")
            For Each s As String In lst1
                Console.WriteLine(s)
            Next
            Dim lst2 As List(Of String) = Ser(Of List(Of String)).String2Object(Ser(Of List(Of String)).Object2String(lst1))
            For Each s As String In lst2
                Console.WriteLine(s)
            Next
        End Sub
    End Class
End Namespace
Avatar billede jobless Nybegynder
09. februar 2010 - 18:11 #13
Tak for hjælpen, det har hjulpet mig videre med mit projekt
Avatar billede jobless Nybegynder
09. februar 2010 - 18:12 #14
(lægger du lige et svar ?)
Avatar billede arne_v Ekspert
09. februar 2010 - 18:23 #15
kommer her
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester