0

I try to send data from server (TcpListener) to client (TcpClient). I use Windows Form Application and the next code:

Imports System.Text
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.Runtime.InteropServices

Public Class Form1

Private Server As TcpListener = Nothing
Private ServerThread As Thread = Nothing
Dim tcpclnt As TcpClient
Dim stream As NetworkStream

Public Shared bytes(1024) As Byte
Public Shared data As String = Nothing


Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Shown
    Server = New TcpListener(IPAddress.Any, 40000)
    ServerThread = New Thread(AddressOf ConnectionListener)
    ServerThread.IsBackground = True
    ServerThread.Start()
    TextBox1.Text = "Server started!"

End Sub

Private Sub ConnectionListener()
    Try
        Server.Start()


        While True
            Dim myClient As TcpClient = Server.AcceptTcpClient()
            Dim T As New Thread(AddressOf SomeClientActions)
            T.Start(myClient)
            Invoke(Sub() TextBox1.Text = TextBox1.Text + Environment.NewLine + "Client connected")


            ' HERE IM TRYING TO READ DATA FROM STREAM
            stream = myClient.GetStream()
            Dim i As Int32
            i = stream.Read(bytes, 0, bytes.Length)

            While True
                ' Translate data bytes to a ASCII string.
                data = System.Text.Encoding.ASCII.GetString(bytes, 0, i)
                Invoke(Sub() TextBox3.Text = "Received: {0}" + data)

                ' Process the data sent by the client.
                data = data.ToUpper()
                Dim msg As Byte() = System.Text.Encoding.ASCII.GetBytes(data)

                ' Send back a response.
                stream.Write(msg, 0, msg.Length)
                Invoke(Sub() TextBox3.Text = "Sent: {0}" + data)

                i = stream.Read(bytes, 0, bytes.Length)

           End While


            myClient.Close()
        End While

    Catch ex As Exception
        MessageBox.Show("Unable to Accept Connections", "Server Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    End Try
    Application.ExitThread()

End Sub

Private Sub SomeClientActions(ByVal client As Object)
    ' ... do something with "client" in here ...
    ' MAYBE SOME CODE HERE?..
End Sub


Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    Server.Stop()
End Sub


Private Sub ButtonClientConnection_Click(sender As Object, e As EventArgs) Handles Button2.Click
    tcpclnt = New TcpClient()
    tcpclnt.Connect("127.0.0.115", 40000)
End Sub

Private Sub ButtonSendData_Click(sender As Object, e As EventArgs) Handles Button3.Click
    ' HERE IM TRYING TO WRITE DATA TO STREAM FROM TEXTBOX
    Dim msg As New System.IO.StringReader(TextBox2.Text)
    Dim msgstr As String = msg.ReadToEnd
    Dim msgbyte() As Byte = Encoding.UTF8.GetBytes(msgstr)
    stream.Write(msgbyte, 0, msgbyte.Length)
End Sub


End Class

What I'm trying to do: I create server, then press button ButtonClientConnection' and create and connect client (TcpClient). That works - I get stringsServer startedandClient connected` in textbox1.

Now I want to do: put some text in textbox2, press button ButtonSendData and transmit this data from client to server through the stream and write this data to another textbox (textbox3). My attempts are here in the code, but nothing is happens - As I see in debugger I write some data in stream, but can't read it because my code for reading data from stream executes only 1 time at client connection.

How to read data permanently? And write it correctly to stream by pressing ButtonSendData? I made some workaround and it looks like it stuck at line:

i = stream.Read(bytes, 0, bytes.Length)

Code stops here and can't go further in this thread.

Visual Vincent
  • 18,045
  • 5
  • 28
  • 75
Mikhail_Sam
  • 10,602
  • 11
  • 66
  • 102
  • [**`NetworkStread.Read()`**](https://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.read(v=vs.110).aspx) blocks the calling thread until there's something to receive, so execution should continue when you send data. – Visual Vincent Mar 27 '17 at 11:22
  • @VisualVincent Aha! So I just send data incorrectly? Can you take a look at my `ButtonSendData_Click` function. Maybe I do it in another thread? – Mikhail_Sam Mar 27 '17 at 11:26

1 Answers1

1

You're sending data through the wrong stream. stream is the server's stream, but you have no stream for tcpclnt.

Try this:

Dim clientstream As NetworkStream

Private Sub ButtonClientConnection_Click(sender As Object, e As EventArgs) Handles Button2.Click
    tcpclnt = New TcpClient()
    tcpclnt.Connect("127.0.0.115", 40000)
    clientstream = tcpclnt.GetStream()
End Sub

Private Sub ButtonSendData_Click(sender As Object, e As EventArgs) Handles Button3.Click
    Dim msgbyte() As Byte = Encoding.UTF8.GetBytes(TextBox2.Text)
    clientstream.Write(msgbyte, 0, msgbyte.Length)
End Sub

As you see I have also removed the StringReader because it was completely unnecessary. You were creating it only to read it back to a string again, where you can just get the bytes from TextBox2.Text directly instead.

Visual Vincent
  • 18,045
  • 5
  • 28
  • 75
  • Visual Vincent, thank you again for so fast reply! I remove surplus lines in `ButtonSendData_Click`. I comment stream definition in `Sub ConnectionListener` but it still stuck at line `i = clientstream.Read(bytes, 0, bytes.Length)` . Can you watch it one more time please! I add all edits in code in my question. – Mikhail_Sam Mar 27 '17 at 11:58
  • @Mikhail_Sam : Nonono, you're not supposed to change _**anything else**_ than what I show in my answer. You need the two different streams: client and server. – Visual Vincent Mar 27 '17 at 12:00
  • @Mikhail_Sam : If the _**server**_ receives from the _**client stream**_ then you will never get the data that you send from the _**client stream**_. The client sends to the server stream and vice versa. -- You ought to divide this into two applications (or at least two forms) so that you don't mix them up so easily. – Visual Vincent Mar 27 '17 at 12:03
  • @Mikhail_Sam : Here's a small illustration of how it needs to be divided: http://imgur.com/KCnQ6m3 – Visual Vincent Mar 27 '17 at 12:13
  • I got it! Now it works and I can send and collect data! One last problem: I can't understand how to display received data only once: I put text in textbox2, press SendData, it writes to `clientstream`. Then `stream` became active (we return to ConnectionListener` function), it read data from `stream` and... and what? In my loop now it puts this text in TextBox3 (yep, it is what I want) but it is infinity loop. How to say him to read `stream` always and if its not empty put data to TextBox3? Or it's better to ask another question about this? – Mikhail_Sam Mar 27 '17 at 12:25
  • @Mikhail_Sam : Update the question with your new code, please. – Visual Vincent Mar 27 '17 at 12:27
  • I GOT IT! I just add `i = stream.Read(...)` inside this infinity loop, so he always waits for the next data! Thank you very much! Give me an advice please: do I need to post correct code in question now? Instead of this incorrect code? – Mikhail_Sam Mar 27 '17 at 12:31
  • @Mikhail_Sam : Well yes, you have to wait for new data :). And no, you don't need to post your new code. I will do a rollback to the previous edit though since others might misinterpret the current one and my answer. – Visual Vincent Mar 27 '17 at 12:33