Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

I am trying to create an application, one on a server and the other on a networked PC. What I want to do is send information from the PC app. to the server app.

 

I have the following code which allow information to be sent when the applications are launched, so they are able to talk to each other. The only problem I have is that the applications both freeze. What I want to do is have the sockets running in a different thread so that PC app. can send information from the main form to the server app. and that information can then be displayed on the server main form e.g. information entered in a text field.

 

Below is the code that creates the socket, and this passes information successfully, but as I said it freezes the applications.

 

Imports System.Net.Sockets
Imports System.Text

Public Class Form1
   Dim tcpClient As New System.Net.Sockets.TcpClient()


   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

   End Sub

   Private Sub runClient(ByVal message As String)
       Dim networkStream As NetworkStream = tcpClient.GetStream()
       If networkStream.CanWrite And networkStream.CanRead Then
           ' Do a simple write. 
           Dim sendBytes As [byte]() = Encoding.ASCII.GetBytes(message)
           networkStream.Write(sendBytes, 0, sendBytes.Length)
           ' Read the NetworkStream into a byte buffer. 
           Dim bytes(tcpClient.ReceiveBufferSize) As Byte
           networkStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
           ' Output the data received from the host to the console. 
           Dim returndata As String = Encoding.ASCII.GetString(bytes)
           Console.WriteLine("Host returned: " + returndata)
       Else
           If Not networkStream.CanRead Then
               Console.WriteLine("cannot not write data to this stream")
               tcpClient.Close()
           Else
               If Not networkStream.CanWrite Then
                   Console.WriteLine("cannot read data from this stream")
                   tcpClient.Close()
               End If
           End If
       End If
       ' pause so user can view the console output 
       Console.ReadLine()
   End Sub

   Private Sub runServer()
       ' Must listen on correct port- must be same as port client wants to connect on. 
       Const portNumber As Integer = 8000
       Dim IP As System.Net.IPAddress
       IP = System.Net.IPAddress.Parse(Me.txtIP.Text)

       Dim tcpListener As New TcpListener(IP, portNumber)
       tcpListener.Start()
       Console.WriteLine("Waiting for connection...")
       Try
           'Accept the pending client connection and return             'a TcpClient initialized for communication. 
           Dim tcpClient As TcpClient = tcpListener.AcceptTcpClient()
           Console.WriteLine("Connection accepted.")
           ' Get the stream 
           Dim networkStream As NetworkStream = tcpClient.GetStream()
           ' Read the stream into a byte array 
           Dim bytes(tcpClient.ReceiveBufferSize) As Byte
           networkStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
           ' Return the data received from the client to the console. 
           Dim clientdata As String = Encoding.ASCII.GetString(bytes)
           Console.WriteLine("Client sent: " + clientdata)
           Dim responseString As String = "Connected to server."
           Dim sendBytes As [byte]() = Encoding.ASCII.GetBytes(responseString)
           networkStream.Write(sendBytes, 0, sendBytes.Length)
           Console.WriteLine("Message Sent /> : " + responseString)
           'Any communication with the remote client using the TcpClient can go here. 
           'Close TcpListener and TcpClient. 
           tcpClient.Close()
           tcpListener.Stop()
           Console.WriteLine("exit")
           Console.ReadLine()
       Catch e As Exception
           Console.WriteLine(e.ToString())
           Console.ReadLine()
       End Try
   End Sub

   Private Sub Panel1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Panel1.MouseMove
       Me.txtStatus.Text = "X: " & e.X.ToString & " Y: " & e.Y.ToString

       If Me.radClient.Checked = True Then
           runClient("X: " & e.X.ToString & " Y: " & e.Y.ToString)
       End If
   End Sub

   Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click
       If Me.radClient.Checked = True Then
           tcpClient.Connect(Me.txtIP.Text, 8000)
           runClient("Connect from machine with IP address " & Me.txtIP.Text)
       Else
           runServer()
       End If
   End Sub

   Private Sub btnDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisconnect.Click
       If Me.radClient.Checked = True Then
           tcpClient.Close()
       End If
   End Sub
End Class

 

Any help would be appreshiated

 

Thanks

 

Simon

  • 3 months later...
Posted
http://www.xtremedotnettalk.com/showthread.php?t=85665 has a fairly basic example of using sockets from background threads - it might be worth a quick look.

Hi Plausibly,

 

I had a similar question, so I looked at your code before posting (sometimes reading other posts really does help!).

 

Your code reads from the port all the time (while True) until something is found, then it sends that to another thread. You even mention in a comment that this wasn't the best technique.

 

I came across the WaitForSingleEvent() API a few years back, which allows the thread to enter a sleep state. The data trigger the thread to resume when it arrives. With .NET, I think WaitHandle with WaitHandle.WaitOne would be better.

 

Any thoughts? Is this what WaitHandle is for? Is there something better?

  • Administrators
Posted

AcceptTcpClient is a blocking call anyway - it waits for incoming connections before proceeding (hence the reason it isn't run from the main UI thread).

 

The comment was really aimed at the while true construct - normally I prefer to have a proper exit condition rather than just quitting out of a loop.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

  • 1 year later...
Posted
AcceptTcpClient is a blocking call anyway - it waits for incoming connections before proceeding (hence the reason it isn't run from the main UI thread).

 

The comment was really aimed at the while true construct - normally I prefer to have a proper exit condition rather than just quitting out of a loop.

 

Thanks for this bit of information, i never realised that it waits for the incomming before proceeding but now i think about it it seems rather obvious lol and i think i've been a bit dumb.

 

But they do say that you learn something new everyday and this is my thing for today i guess :)

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...