Avatar billede wired Nybegynder
05. august 2004 - 01:33 Der er 48 kommentarer og
1 løsning

Client/Server application

Jeg ønsker at lave en client/server applikation i vb.net,
således at en client kan sende en string/fil til serveren, hvorefter klient får besked om det lykkedes. Dette skal ske hvert ms.
Avatar billede wired Nybegynder
05. august 2004 - 01:38 #1
Hvis det kan gøres smartere og nemmere på en anden måde er det også ok, bare der sendes over et TCP/IP netværk. Hvis det f.eks. kunne gøres via en browser ville det være vildt fedt.. Men der er vist ingen knap i en browser som kan reagere hurtigt nok til at sende f.eks. 3 gang inde for et sekund, men lad høre.
Avatar billede arne_v Ekspert
05. august 2004 - 06:55 #2
Det er ret nemt at lave noget client/server i VB.NET.

Du kan starte med dette simple eksempel:

client:

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

Class Client
    Public Shared Sub Main(ByVal args As String())
        Dim client As TcpClient = New TcpClient ("localhost", 1234)
        Dim wrt As StreamWriter = New StreamWriter (client.GetStream)
        Dim rdr As StreamReader = New StreamReader (client.GetStream)
        Dim outmsg As String
        Dim inmsg As String
        While True
            outmsg = "Dette er en streng eller en fil"
            wrt.WriteLine(outmsg)
            wrt.Flush
            inmsg = rdr.ReadLine
            Console.WriteLine(inmsg)
            Thread.Sleep(500)
        End While
        wrt.Close
        rdr.Close
        client.Close
    End Sub
End Class

server:

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

Class Server
    Public Shared Sub Main(ByVal args As String())
        Dim server As TcpListener = New TcpListener (IPAddress.Any, 1234)
        server.Start
        Dim client As TcpClient = server.AcceptTcpClient
        Dim rdr As StreamReader = New StreamReader (client.GetStream)
        Dim wrt As StreamWriter = New StreamWriter (client.GetStream)
        Dim outmsg As String
        Dim inmsg As String
        inmsg = rdr.ReadLine
        While Not (inmsg Is Nothing)
            Console.WriteLine(inmsg)
            outmsg = "OK"
            wrt.WriteLine(outmsg)
            wrt.Flush
            inmsg = rdr.ReadLine
        End While
        rdr.Close
        wrt.Close
        client.Close
        server.Stop
    End Sub
End Class
Avatar billede wired Nybegynder
05. august 2004 - 23:02 #3
Fedt Arne...Det ser rigtig godt ud. Er det ikke muligt at du kan kommentere det lidt da der er en del linier som jeg er i tvivl om.
Avatar billede arne_v Ekspert
05. august 2004 - 23:10 #4
Imports System
Imports System.IO
Imports System.Net.Sockets
Imports System.Threading

Class Client
    Public Shared Sub Main(ByVal args As String())
        ' connect til localhost port 1234
        Dim client As TcpClient = New TcpClient ("localhost", 1234)
        ' hent writer og reader til at skrive og læse med
        Dim wrt As StreamWriter = New StreamWriter (client.GetStream)
        Dim rdr As StreamReader = New StreamReader (client.GetStream)
        Dim outmsg As String
        Dim inmsg As String
        ' uendelig løkke med:
        '  skriv til server
        '  læse fra server
        '  udskriv det læste til skærmen       
        While True
            outmsg = "Dette er en streng eller en fil"
            wrt.WriteLine(outmsg)
            wrt.Flush
            inmsg = rdr.ReadLine
            Console.WriteLine(inmsg)
            Thread.Sleep(500)
        End While
        ' luk alting
        wrt.Close
        rdr.Close
        client.Close
    End Sub
End Class
Avatar billede arne_v Ekspert
05. august 2004 - 23:12 #5
Imports System
Imports System.IO
Imports System.Net
Imports System.Net.Sockets

Class Server
    Public Shared Sub Main(ByVal args As String())
        ' lyt på port 1234
        Dim server As TcpListener = New TcpListener (IPAddress.Any, 1234)
        server.Start
        ' vent på connection
        Dim client As TcpClient = server.AcceptTcpClient
        ' hent writer og reader til at skrive og læse med
        Dim rdr As StreamReader = New StreamReader (client.GetStream)
        Dim wrt As StreamWriter = New StreamWriter (client.GetStream)
        Dim outmsg As String
        Dim inmsg As String
        ' så længe der kommer data ind:
        '  læs data fra client
        '  udskriv data til skærmen
        '  skriv svar tilbage til client
        inmsg = rdr.ReadLine
        While Not (inmsg Is Nothing)
            Console.WriteLine(inmsg)
            outmsg = "OK"
            wrt.WriteLine(outmsg)
            wrt.Flush
            inmsg = rdr.ReadLine
        End While
        ' luk alting
        rdr.Close
        wrt.Close
        client.Close
        server.Stop
    End Sub
End Class
Avatar billede wired Nybegynder
05. august 2004 - 23:23 #6
Ok, mit problem er nok at der ikke kom noget på skærmen og at den kom med en fejl hvis det ene program blev startet noget før end det andet. Dvs. det ene program kan ikke køre uden det anden uden at kommer med en fejl medl. Det kan nok klares med en try... Men jeg forstår bare ikke hvorfor der ikke kommer noget på skærmen... åhh.. det er nok fordi at jeg ikke programmere i console -mode men i grafisk...
Anyway 1000 tak... alle pointene er dig velfortjent.
Avatar billede arne_v Ekspert
05. august 2004 - 23:32 #7
Server skal startes før client.

Det er ganske rigtigt 2 console programmer.
Avatar billede wired Nybegynder
05. august 2004 - 23:34 #8
Den fryser i:
  Dim server As TcpListener = New TcpListener(IPAddress.Any, 1234)

og i:
  Dim client As TcpClient = New TcpClient("localhost", 1234)

Formoder at jeg skal sætte try rundt om det hele.
Avatar billede arne_v Ekspert
05. august 2004 - 23:36 #9
Flowet skal være:

serveren starter med at lytte med

serveren venter på connection fra client

client startes og connecter

server kører videre
Avatar billede wired Nybegynder
05. august 2004 - 23:45 #10
Jeg er opmærksom på at dette er et spørgsmål udenfor og du siger bare hvis du skal have points, men er det - på en nem måde - muligt at få serveren til at lave andet mens den venter på at få et svar og når den så få et svar så hopper den til en given funktion?
Som jeg ser det - ser det ud som om at man skal lade client kalde proceduren hvert x ms (ikke fordi jeg ved hvordan det nemmest gøres). Eller er der en nemmere løsning?
Avatar billede arne_v Ekspert
05. august 2004 - 23:47 #11
Typisk gør man det at man på serveren starter en ny tråd til at håndtere en client,
når man har accept'et en connect.
Avatar billede arne_v Ekspert
05. august 2004 - 23:51 #12
Hvis det er en GUI måske:
  - hoved tråd til GUI
  - tråd som står i løkke og accepterer conenctions
  - en tråd per client som er connectet
Avatar billede wired Nybegynder
05. august 2004 - 23:55 #13
Du er en haj. Ærbædigst.

Jeg har Visual Basic.NET Bible og der er ikke et ord om nogle af disse ting. Skod :-)

Endnu en gang tak... så slutter jeg herfra.
Avatar billede wired Nybegynder
05. august 2004 - 23:57 #14
Men hvis du lige har et eksempel på at lave det med tråde, giver jeg gerne 40 point for det, hvis det er ok? :-)
Avatar billede arne_v Ekspert
05. august 2004 - 23:59 #15
Jeg kan prøve.
Avatar billede arne_v Ekspert
06. august 2004 - 00:11 #16
Den her version af server venter på client connecter men så modtager den både
beskeder fra client og laver noget andet:

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

Public Class T
    Private client As TcpClient
    Public Sub New(cli As TcpClient)
        client = cli
    End Sub
    Public Sub Run()
        Dim rdr As StreamReader = New StreamReader (client.GetStream)
        Dim wrt As StreamWriter = New StreamWriter (client.GetStream)
        Dim outmsg As String
        Dim inmsg As String
        inmsg = rdr.ReadLine
        While Not (inmsg Is Nothing)
            Console.WriteLine(inmsg)
            outmsg = "OK"
            wrt.WriteLine(outmsg)
            wrt.Flush
            inmsg = rdr.ReadLine
        End While
        rdr.Close
        wrt.Close
    End Sub
End Class

Class Server
    Public Shared Sub Main(ByVal args As String())
        Dim server As TcpListener = New TcpListener (IPAddress.Any, 1234)
        server.Start
        Dim client As TcpClient = server.AcceptTcpClient
        Dim clienthandler As T = New T(client)
        Call (New Thread (New ThreadStart (AddressOf clienthandler.Run))).Start
        While True
            Console.WriteLine("I am doing something")
            Thread.Sleep(250)
        End While
        client.Close
        server.Stop
    End Sub
End Class
Avatar billede wired Nybegynder
06. august 2004 - 00:11 #17
:-D
Avatar billede arne_v Ekspert
06. august 2004 - 00:15 #18
Den her version af server lader venten på connect ske i tråden så
den kan gå igang med noget andet med det samme uden at vente på client:

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

Public Class T
    Private server As TcpListener
    Public Sub New(srv As TcpListener)
        server = srv
    End Sub
    Public Sub Run()
        Dim client As TcpClient = server.AcceptTcpClient
        Dim rdr As StreamReader = New StreamReader (client.GetStream)
        Dim wrt As StreamWriter = New StreamWriter (client.GetStream)
        Dim outmsg As String
        Dim inmsg As String
        inmsg = rdr.ReadLine
        While Not (inmsg Is Nothing)
            Console.WriteLine(inmsg)
            outmsg = "OK"
            wrt.WriteLine(outmsg)
            wrt.Flush
            inmsg = rdr.ReadLine
        End While
        rdr.Close
        wrt.Close
        client.Close
    End Sub
End Class

Class Server
    Public Shared Sub Main(ByVal args As String())
        Dim server As TcpListener = New TcpListener (IPAddress.Any, 1234)
        server.Start
        Dim clienthandler As T = New T(server)
        Call (New Thread (New ThreadStart (AddressOf clienthandler.Run))).Start
        While True
            Console.WriteLine("I am doing something")
            Thread.Sleep(250)
        End While
        server.Stop
    End Sub
End Class
Avatar billede arne_v Ekspert
06. august 2004 - 00:16 #19
Som du kan se så kan det laves på mange måder. Og du skal vælge den som
passer til din kontekst.

Men metoden med at starte tråde er meget nyttig at kende.
Avatar billede wired Nybegynder
06. august 2004 - 00:27 #20
Min den fryser ved linien:
  Dim server As TcpListener = New TcpListener (IPAddress.Any, 1234)

Hvorfor har du:
  ByVal args As String()
Jeg har haft fjernet det hver gang.
Avatar billede wired Nybegynder
06. august 2004 - 00:28 #21
Ups.. Nej det var en fejl. Den stopper alligevel ikke ved linien
Avatar billede wired Nybegynder
06. august 2004 - 00:32 #22
Det ser rigtig godt ud, men hvad sker der i linierne:
    Dim clienthandler As T = New T(server)
    Call (New Thread(New ThreadStart(AddressOf clienthandler.Run))).Start()
Avatar billede wired Nybegynder
06. august 2004 - 00:52 #23
Kan man evt. udlade at lave en ny class (T) og bare nøjes med subrutinerne?
Avatar billede wired Nybegynder
06. august 2004 - 00:56 #24
Således at jeg kan ændre i de objecter jeg har lavet i de andre class's
Avatar billede arne_v Ekspert
06. august 2004 - 07:38 #25
Nogle andre sprog insisterer på at man skal angive kommando linie argumenterne til
Main selvom man ikke har planer om at bruge dem. Det er bare en vane.
Avatar billede arne_v Ekspert
06. august 2004 - 07:39 #26
' lav et client handler objekt som skal bruges til at køre tråd med
Dim clienthandler As T = New T(server)
' start en ny tråd med clienthandler objektet og Run metoden
Call (New Thread(New ThreadStart(AddressOf clienthandler.Run))).Start()
Avatar billede arne_v Ekspert
06. august 2004 - 07:52 #27
Du kan godt køre en metode i samme klasse.

(og ThreadStart er iøvrigt optional i VB.NET)
Avatar billede arne_v Ekspert
06. august 2004 - 07:52 #28
Demo af forskellige måder at starte en tråd på:

Imports System
Imports System.Threading

Public Class T
    Public Sub Run()
        Console.WriteLine("T Run")
    End Sub
End Class

Module Main
    Public Sub Run()
        Console.WriteLine("Run")
    End Sub
    Sub Main()
        Dim thr As T = new T
        Call (New Thread(New ThreadStart(AddressOf thr.Run))).Start
        Call (New Thread(AddressOf thr.Run)).Start
        Call (New Thread(New ThreadStart(AddressOf Run))).Start
        Call (New Thread(AddressOf Run)).Start
    End Sub
End Module
Avatar billede wired Nybegynder
06. august 2004 - 09:03 #29
Perfekt.. og utroligt hurtigt.

Jeg har lagt point til dig i http://www.eksperten.dk/spm/526777

Har du en bog du kan anbefale i forbindelse med obj-programmeret i vb.net?

(åh og et sidste lille ? Når jeg i Tråden (T) og vil tilføje noget til en listbox i classen "server" kan jeg ikke skrive Form1.listbox1.item.add("hej"), hvorfor ikk'?)
Avatar billede arne_v Ekspert
06. august 2004 - 09:29 #30
Jeg har set det.

Jeg har faktisk ikke en VB.NET bog selv. En mulighed var
Professional VB.NET / Wrox. Jeg har den tilsvarende C# bog og
den er god. Anmeldelserne på Amazon er dog lidt blandede.

Jeg formoder at du enten skal kalde en metode i den klasse der har
Form1 eller at du skal have en reference til Form1 sendt med over i T.
Avatar billede wired Nybegynder
07. august 2004 - 20:49 #31
Hej Arne
Jeg formoder at dine tråde i 2. og 3. sidste eksempel aldrig bliver lukket. Betyder det ikke at de aldrig forsvinder fra memory og dermed fylder efter man har lukke applicationen (pga. while true...)? eller ?

Bør man lave en Form1_Closing(...) Handles MyBase.Closing
  eller er jeg helt på afspor?
Avatar billede arne_v Ekspert
07. august 2004 - 22:10 #32
Når applikationen lukker ned så dør alle trådene.

Men derfor bør der alligevel laves noget kode som får alt lukket pænt ned.

Men præcis hvordan afhænger meget af konteksten.

Et thread objekt har nogle metoder Abort, Interrupt og Join som kan bruges.
Avatar billede wired Nybegynder
08. august 2004 - 00:06 #33
Jeg har lavet nedenstående og hver gang jeg lukker applikationen forbliver processen i windows jobliste, og applicationen kan ikke startes igen før end jeg har afbrudt den fra windows jobliste.

  Public Sub lyt()
    ListBox1.Items.Add("logon") ' Add the data to the list
    While True
      Dim server As TcpListener = New TcpListener(IPAddress.Any, 1234)
      server.Start() ' Start listen for client request
      Dim inmsg As String
      Dim client As TcpClient = server.AcceptTcpClient ' Wait for a client to connect
      ' ... connected
      Dim rdr As StreamReader = New StreamReader(client.GetStream) ' Prepare for data
      inmsg = rdr.ReadLine ' Get first steam of data
      While Not (inmsg Is Nothing)
        ListBox1.Items.Add(inmsg) ' Add the data to the list
        inmsg = rdr.ReadLine
      End While
      rdr.Close() ' close data stream
      client.Close() ' close client connection
      server.Stop() ' stop listen
    End While
  End Sub

  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Call New Thread(AddressOf lyt).Start() ' Start the thread
  End Sub
Avatar billede arne_v Ekspert
08. august 2004 - 00:10 #34
Applikationen lukker ikke ned fordi main thread lukkes.
Avatar billede arne_v Ekspert
08. august 2004 - 00:12 #35
Hvis du har en variabel:

Private t As Thread

og starter tråden med:

t = New Thread(AddressOf lyt)
Call t.Start()

så kan du stoppe den med:

t.Abort()
t.Join()
Avatar billede arne_v Ekspert
08. august 2004 - 00:18 #36
En mere brutal løsning er at afslutte programmet med:

Environment.Exit(0)

som også burde lukke helt ned.
Avatar billede wired Nybegynder
09. august 2004 - 20:54 #37
Jeg forstår det ikke, hele min app. fryser ved:
  Dim client As TcpClient = server.AcceptTcpClient()
selv om er i tråden. Var det ikke netop det tråden skulle løse?

Mit prg. ser således ud nu:

  Class lyt
    Private server As TcpListener
    Public Event TreadDone(ByVal minmsg As String)

    Public Sub New(ByVal srv As TcpListener)
      server = srv
    End Sub
    Public Sub GetData()
      While True
        Dim client As TcpClient = server.AcceptTcpClient()
        ' ... connected
        Dim rdr As StreamReader = New StreamReader(client.GetStream)
        Dim inmsg As String
        inmsg = rdr.ReadLine
        While Not (inmsg Is Nothing)
          RaiseEvent TreadDone(inmsg)
          inmsg = rdr.ReadLine
        End While
        rdr.Close()
        client.Close()
      End While
      server.Stop()
    End Sub
  End Class

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim server As TcpListener = New TcpListener(IPAddress.Any, 1234)
    server.Start()
    ClientData = New lyt(server)

    Call (New Thread(New ThreadStart(AddressOf ClientData.GetData))).Start()
  End Sub
Avatar billede wired Nybegynder
09. august 2004 - 21:06 #38
Glemte måske (men er nok mindre vigtigt):

  Dim WithEvents ClientData As lyt

  Private Sub AddItem(ByVal minmsg As String) Handles ClientData.TreadDone
    If Not (minmsg Is Nothing) Then
      ListBox1.Items.Add(minmsg) ' Add the data to the list
    End If
  End Sub
Avatar billede arne_v Ekspert
09. august 2004 - 22:15 #39
Tråden der accepter bør hænge indtil der kommer en connection, men resten
af applikationen bør køre videre.
Avatar billede wired Nybegynder
09. august 2004 - 22:21 #40
Og det gør den ikke...
Avatar billede wired Nybegynder
09. august 2004 - 22:26 #41
underligt ikk'?
Avatar billede arne_v Ekspert
09. august 2004 - 23:08 #42
Meget.

Følgende virker hos mig:

Imports System
Imports System.Drawing
Imports System.Windows.Forms
Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading

Namespace DefaultNamespace
    Public Class MainClass
        Public Shared Sub Main
            Dim mf As New MainForm
            Dim server As TcpListener = New TcpListener(IPAddress.Any, 1234)
            server.Start()
            Dim t As Listen = New Listen(server, mf)
            Call (New Thread(New ThreadStart(AddressOf t.WaitForConnectAndAccept))).Start()
            mf.ShowDialog()
        End Sub
    End Class
    Public Class Listen
        Private server As TcpListener
        Private mainform As MainForm
        Public Sub New(srv As TcpListener, mf As MainForm)
            server = srv
            mainform = mf
        End Sub
        Public Sub WaitForConnectAndAccept()
            MessageBox.Show("started")
            While True
                Dim client As TcpClient = server.AcceptTcpClient
                Dim rdr As StreamReader = New StreamReader(client.GetStream)
                Dim line As String = rdr.ReadLine
                mainform.SetLabel2(line)
                rdr.Close
                client.Close
            End While
            server.Stop()
        End Sub
    End Class
    Public Class MainForm
        Inherits System.Windows.Forms.Form
        Private label1 As Label
        Private button1 As Button
        Private button2 As Button
        Private label2 As Label
        Private button3 As Button
        Public Sub SetLabel2(txt As String)
            label2.Text = txt
        End Sub
        Public Sub New()
            MyBase.New
            Me.InitializeComponent
        End Sub
        Private Sub InitializeComponent()
            SuspendLayout
           
            ClientSize = New Size(300, 300)
            Name = "MainForm"
            Text = "MainForm"

            label1 = New Label
            label1.Location = New Point(50, 50)
            label1.Size = new Size(200, 25)
            label1.Name = "label1"
            label1.TabIndex = 0
            label1.Text = "Du har ikke trykket endnu"
            Controls.Add(label1)

            button1 = New Button
            button1.Location = New Point(50, 100)
            button1.Size = new Size(200, 25)
            button1.Name = "button1"
            button1.TabIndex = 1
            button1.Text = "A"
            AddHandler button1.Click, AddressOf ClickA
            Controls.Add(button1)

            button2 = New Button
            button2.Location = New Point(50, 150)
            button2.Size = new Size(200, 25)
            button2.Name = "button2"
            button2.TabIndex = 2
            button2.Text = "B"
            AddHandler button2.Click, AddressOf ClickB
            Controls.Add(button2)

            label2 = New Label
            label2.Location = New Point(50, 200)
            label2.Size = new Size(200, 25)
            label2.Name = "label2"
            label2.TabIndex = 3
            label2.Text = ""
            Controls.Add(label2)

            button3 = New Button
            button3.Location = New Point(50, 250)
            button3.Size = new Size(200, 25)
            button3.Name = "button3"
            button3.TabIndex = 4
            button3.Text = "Exit"
            AddHandler button3.Click, AddressOf ClickExit
            Controls.Add(button3)

            ResumeLayout(false)
        End Sub
        Private Sub ClickA(o As Object, e As EventArgs)
            label1.Text = "Du har trykket A"
        End Sub
        Private Sub ClickB(o As Object, e As EventArgs)
            label1.Text = "Du har trykket B"
        End Sub
        Private Sub ClickExit(o As Object, e As EventArgs)
            Application.Exit
            Environment.Exit(0)
        End Sub
    End Class
End Namespace
Avatar billede wired Nybegynder
11. august 2004 - 00:30 #43
Jeg tror jeg har fundet ud af hvad problemet var. Det har noget en binding at gøre.
F.eks. fungere følgende heller ikke pga.:

  DataGrid1.SetDataBinding(DS, "AllData")

Men udmaskes den fungere det, men så får jeg bare ikke mit resultat på skærmen.. øv.

Imports System
Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.Data
Public Class Form1
  Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "

  Public Sub New()
    MyBase.New()

    'This call is required by the Windows Form Designer.
    InitializeComponent()

    'Add any initialization after the InitializeComponent() call

  End Sub

  'Form overrides dispose to clean up the component list.
  Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
    If disposing Then
      If Not (components Is Nothing) Then
        components.Dispose()
      End If
    End If
    MyBase.Dispose(disposing)
  End Sub

  'Required by the Windows Form Designer
  Private components As System.ComponentModel.IContainer

  'NOTE: The following procedure is required by the Windows Form Designer
  'It can be modified using the Windows Form Designer. 
  'Do not modify it using the code editor.
  Friend WithEvents Button1 As System.Windows.Forms.Button
  Friend WithEvents ListBox1 As System.Windows.Forms.ListBox
  Friend WithEvents Button2 As System.Windows.Forms.Button
  Friend WithEvents DataGrid1 As System.Windows.Forms.DataGrid
  Friend WithEvents Label1 As System.Windows.Forms.Label

  <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
    Me.Button1 = New System.Windows.Forms.Button
    Me.ListBox1 = New System.Windows.Forms.ListBox
    Me.Button2 = New System.Windows.Forms.Button
    Me.DataGrid1 = New System.Windows.Forms.DataGrid
    Me.Label1 = New System.Windows.Forms.Label
    CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).BeginInit()
    Me.SuspendLayout()
    '
    'Button1
    '
    Me.Button1.Location = New System.Drawing.Point(16, 16)
    Me.Button1.Name = "Button1"
    Me.Button1.TabIndex = 0
    Me.Button1.Text = "Modtag"
    '
    'ListBox1
    '
    Me.ListBox1.Location = New System.Drawing.Point(104, 16)
    Me.ListBox1.Name = "ListBox1"
    Me.ListBox1.Size = New System.Drawing.Size(176, 108)
    Me.ListBox1.TabIndex = 1
    '
    'Button2
    '
    Me.Button2.Location = New System.Drawing.Point(16, 48)
    Me.Button2.Name = "Button2"
    Me.Button2.TabIndex = 2
    Me.Button2.Text = "Blink"
    '
    'DataGrid1
    '
    Me.DataGrid1.DataMember = ""
    Me.DataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText
    Me.DataGrid1.Location = New System.Drawing.Point(16, 136)
    Me.DataGrid1.Name = "DataGrid1"
    Me.DataGrid1.Size = New System.Drawing.Size(408, 280)
    Me.DataGrid1.TabIndex = 3
    '
    'Label1
    '
    Me.Label1.Location = New System.Drawing.Point(288, 16)
    Me.Label1.Name = "Label1"
    Me.Label1.TabIndex = 4
    Me.Label1.Text = "Label1"
    '
    'Form1
    '
    Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
    Me.ClientSize = New System.Drawing.Size(432, 438)
    Me.Controls.Add(Me.Label1)
    Me.Controls.Add(Me.DataGrid1)
    Me.Controls.Add(Me.Button2)
    Me.Controls.Add(Me.ListBox1)
    Me.Controls.Add(Me.Button1)
    Me.Name = "Form1"
    Me.Text = "Indtaster - Server"
    CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).EndInit()
    Me.ResumeLayout(False)

  End Sub
#End Region

  Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    If Button2.BackColor.ToString = Color.Blue.ToString Then
      Button2.BackColor = Color.Red
    Else
      Button2.BackColor = Color.Blue
    End If
  End Sub
  Function CreateDataSet(ByVal TheDS As DataSet, ByVal TheDT As DataTable, ByVal TableName As String)
    Dim ds As DataSet = TheDS
    Dim dt As DataTable = TheDT
    Dim DC0 As New DataColumn("tal1") ' Create colums to the table
    Dim DC1 As New DataColumn("tal2")
    Dim DC2 As New DataColumn("tal3")
    Dim DC3 As New DataColumn("Kommentar")
    DC3.ColumnName = "Kommentar"
    dt.Columns.Add(DC0) ' Add the columns to the table
    dt.Columns.Add(DC1)
    dt.Columns.Add(DC2)
    dt.Columns.Add(DC3)
    ds.Tables.Add(dt) ' Add the table to the dataset
    Return ds
  End Function
  Public Class Listen
    Private server As TcpListener
    Private mainform As ListBox
    Private TheDataTable As DataTable
    Private MyDR As DataRow
    Public Sub New(ByVal srv As TcpListener, ByVal DT As DataTable, ByVal mf As ListBox)
      server = srv
      mainform = mf
      TheDataTable = DT
    End Sub
    Public Sub WaitForConnectAndAccept()
      While True
        Dim client As TcpClient = server.AcceptTcpClient
        Dim rdr As StreamReader = New StreamReader(client.GetStream)
        Dim line As String = rdr.ReadLine
        mainform.Items.Add(line) ' Add the data to the list

        MyDR = TheDataTable.NewRow
        MyDR(0) = "test"
        TheDataTable.Rows.Add(MyDR)
        TheDataTable.EndInit()

        rdr.Close()
        client.Close()
      End While
      server.Stop()
    End Sub
  End Class

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim DS As DataSet = New DataSet("DSet")  ' Make a dataset
    Dim DT As DataTable = New DataTable("AllData")  ' Make a table
    DS = CreateDataSet(DS, DT, "AllData")
' -------- Udmaskes linien herunder virker det, men ikke med så fryser tråden ----
    DataGrid1.SetDataBinding(DS, "AllData") '

    Dim server As TcpListener = New TcpListener(IPAddress.Any, 1234)
    server.Start()
    Dim t As Listen = New Listen(server, DT, ListBox1)
    Call (New Thread(New ThreadStart(AddressOf t.WaitForConnectAndAccept))).Start()

  End Sub
  Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
    Application.Exit()
    Environment.Exit(0)
  End Sub

End Class
Avatar billede wired Nybegynder
11. august 2004 - 00:34 #44
Jeg er dig meget taknemlig og vil gerne give dig nogle flere point, hvis du kan hjælpe mig med dette problem.. Hvis du vil, hvad vil da være et passende antal points?
Avatar billede arne_v Ekspert
11. august 2004 - 14:30 #45
Lad os bekymre os om point senere.

Jeg er lidt på herrens mark med dette problem. Jeg er ikke GUI mand
og jeg har aldrig brugt DataGrid.

Jeg kommer til at eksperimentere lidt først.
Avatar billede wired Nybegynder
11. august 2004 - 21:24 #46
Det lader til at problemet opstår fordi at der oprettes noget nyt i tråden - i dette tilfælde en ny row - som så tilføjes DataGrid'en. Hvilket sker i linien:

  MyDR = TheDataTable.NewRow
Avatar billede wired Nybegynder
11. august 2004 - 22:44 #47
Nix, det er først når row'en tilføjes tabellen at problemet opstår.
  TheDataTable.Rows.Add(MyDR)
Men det er jo i og for sig også det bindingen sker.
Jeg skal sikkert over i noget invoke/delegate for at undgå tilknytningen, men det kender jeg desværre ikke så meget til. Læste et sted at det måske kunne løses med invoke.
Avatar billede wired Nybegynder
11. august 2004 - 23:46 #48
Jeg kan ikke forklare/forstå hvorfor den fryser når den tilføjer noget til en binding, og har - ind til videre - derfor valgt at fjerne det fra tråden og kun vente på data i tråden. Når tråden modtager data lukker den TCPClienten og stopper TCPListeren, hvorefter den starter en event som derved løser det som skal ske - altså tilføjer data i datagrid'en. Jeg opnår det ventede men forklare ikke problemet. Løsningen må vente... Jeg vil dog gerne give dig nogle point for tiden du har brugt...Jeg ved ikke hvor meget tid du har brugt og hvis jeg spørg dig vil du sikkert bare være for beskeden. At spørge dig om hvad du vil syntes ville være et passende antal point vil sikkert ende med samme resultat. Jeg har derfor lagt 30 point i http://www.eksperten.dk/spm/528479 og takker mange gange for din support.
Avatar billede arne_v Ekspert
11. august 2004 - 23:54 #49
Der må være et eller andet winforms threading issue.

Men jeg har ingen ide om hvordan det hænger sammen.
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