Help! TCP Communications

Friends,

I have a TCP Client, in one project, that connects to a specific IP address and port and "listens" for data.  Now I need some kind of class or module, to run inside of another vb.net project, that will allow my TCP Client to connect to.  Once the TCP client is connected, it waits until data is recieved from this yet to be determinded server class/module.

Does anybody have leads on such a TCP Server?  Sample code or app?   I need all the help I can get!!!

Thanks to a member of this forum, I was given this code that allows me to broadcast out a specific port, but it doesn't give my Client anything to connect to.

Imports System.Net
Imports System.Net.Sockets
Imports System.Text

Public Class SendUpdateCommand

    Public Sub Broadcast()
        Dim sock As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
        sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1)
        Dim iep As New IPEndPoint(Isloopback.Broadcast, 50089)
        Dim msg As Byte() = Encoding.ASCII.GetBytes("Update")
        sock.SendTo(msg, iep)
        sock.Close()
    End Sub

End Class

Thanks,

Eric
indy500fanAsked:
Who is Participating?
 
Bob LearnedCommented:
Imports System.Net
Imports System.Net.Sockets
Imports System.Text.Encoding

Public Class Socket_Library

  Private Class SocketPacket

    Public thisSocket As Socket
    Public dataBuffer As Byte() = New Byte(1024) {}

  End Class 'SocketPacket'


  Public Class SocketEventArgs

    Public Data As String = String.Empty

    Public Sub New(ByVal newData As String)

      Me.Data = newData

    End Sub

  End Class 'SocketEventArgs'

  Private socketListener As Socket
  Private socketWorker As Socket

  Public Event ReceivedData(ByVal sender As Object, ByVal e As SocketEventArgs)


  Public Sub ListenToPort(ByVal portNumber As Integer)

    socketListener = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    Dim ipLocal As IPEndPoint = New IPEndPoint(IPAddress.Any, portNumber)

    Me.socketListener.Bind(ipLocal)
    Me.socketListener.Listen(1)

    Me.socketListener.BeginAccept(New AsyncCallback(AddressOf connectCallbackFunction), Nothing)

  End Sub 'ListenToPort'


  Private Sub connectCallbackFunction(ByVal result As IAsyncResult)

    Try

      socketWorker = socketListener.EndAccept(result)

      Me.WaitForData(socketWorker)

      Me.SendData(socketWorker, "Connected")

    Catch oEx As ObjectDisposedException
      Console.WriteLine("The connection has been closed.")

    Catch sEx As SocketException
      Console.WriteLine(sEx.Message)

    End Try

  End Sub 'connectCallbackFunction'


  Public Sub SendData(ByVal IOsocket As Socket, ByVal messageToSend As String)

    Try

      Console.Write("Sending this message: ")
      Console.Write(messageToSend)
      Console.WriteLine("")

      Dim byteData As Byte() = ASCII.GetBytes(messageToSend)

      IOsocket.Send(byteData)

    Catch sEx As SocketException
      Console.WriteLine(sEx.Message)

    End Try

  End Sub 'SendData'


  Private Sub WaitForData(ByVal IOsocket As System.Net.Sockets.Socket)

    Try

      Dim packet As SocketPacket = New SocketPacket

      packet.thisSocket = IOsocket

      IOsocket.BeginReceive(packet.dataBuffer, 0, packet.dataBuffer.Length, SocketFlags.None, New AsyncCallback(AddressOf dataReceivedCallbackFunction), packet)

    Catch dataException As SocketException

      Console.WriteLine(dataException.Message)

    End Try

  End Sub 'WaitForData'


  Private Sub dataReceivedCallbackFunction(ByVal result As IAsyncResult)

    Try

      Dim packet As SocketPacket = CType(result.AsyncState, SocketPacket)

      Dim size As Integer = packet.thisSocket.EndReceive(result)

      Dim buffer(size + 1) As Char
      Dim decoder As System.Text.Decoder = System.Text.Encoding.UTF8.GetDecoder
      Dim numCharacters As Integer = decoder.GetChars(packet.dataBuffer, 0, size, buffer, 0)
      Dim receivedData As System.String = New System.String(buffer)

      RaiseEvent ReceivedData(Me, New SocketEventArgs(receivedData))

    Catch oEx As ObjectDisposedException

      Console.WriteLine("The connection has been closed.")

    Catch sEx As SocketException

      Console.WriteLine(sEx.Message)

    End Try

  End Sub 'dataReceivedCallbackFunction'

End Class


Bob
0
 
cyberdevil67Commented:
Try this if you have any question let me know.

http://www.codeproject.com/vb/net/VbNetSendReceiveTcp.asp
0
 
indy500fanAuthor Commented:
I'm downloading it now.  I'll be trying it shortly.
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
Bob LearnedCommented:
Are you trying to set up a TCP server?  You are sending out UDP packets, which are connection-less.  Here is some code that I have to listen on a specified port:

Imports System.Text.Encoding

Public Class Socket_Library

  Private Class SocketPacket
    Public thisSocket As Socket
    Public dataBuffer As Byte() = New Byte(1024) {}
  End Class

  Private Shared socketListener As Socket
  Private Shared socketWorker As Socket

  Private Const messageToSend As String = "Hello, client!"


  Public Shared Sub ListenToPort(ByVal portNumber As Integer)

    socketListener = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    Dim ipLocal As IPEndPoint = New IPEndPoint(IPAddress.Any, portNumber)

    socketListener.Bind(ipLocal)
    socketListener.Listen(1)

    socketListener.BeginAccept(New AsyncCallback(AddressOf connectCallbackFunction), Nothing)

  End Sub


  Private Shared Sub connectCallbackFunction(ByVal result As IAsyncResult)

    Try

      socketWorker = socketListener.EndAccept(result)
      WaitForData(socketWorker)
      SendData(socketWorker)

    Catch oEx As ObjectDisposedException
      Console.WriteLine("The connection has been closed.")

    Catch sEx As SocketException
      Console.WriteLine(sEx.Message)

    End Try

  End Sub


  Private Shared Sub SendData(ByVal IOsocket As System.Net.Sockets.Socket)

    Try

      Console.Write("Sending this message: ")
      Console.Write(messageToSend)
      Console.WriteLine("")

      Dim byteData As Byte() = ASCII.GetBytes(messageToSend)

      IOsocket.Send(byteData)

    Catch sEx As SocketException
      Console.WriteLine(sEx.Message)

    End Try
  End Sub


  Private Shared Sub WaitForData(ByVal IOsocket As System.Net.Sockets.Socket)

    Try

      Dim packet As SocketPacket = New SocketPacket

      packet.thisSocket = IOsocket

      IOsocket.BeginReceive(packet.dataBuffer, 0, packet.dataBuffer.Length, SocketFlags.None, New AsyncCallback(AddressOf dataReceivedCallbackFunction), packet)

    Catch dataException As SocketException
      Console.WriteLine(dataException.Message)

    End Try

  End Sub


  Private Shared Sub dataReceivedCallbackFunction(ByVal result As IAsyncResult)

    Try

      Dim packet As SocketPacket = CType(result.AsyncState, SocketPacket)

      Dim size As Integer = packet.thisSocket.EndReceive(result)

      Dim buffer(size + 1) As Char
      Dim decoder As System.Text.Decoder = System.Text.Encoding.UTF8.GetDecoder
      Dim numCharacters As Integer = decoder.GetChars(packet.dataBuffer, 0, size, buffer, 0)
      Dim receivedData As System.String = New System.String(buffer)

    Catch oEx As ObjectDisposedException
      Console.WriteLine("The connection has been closed.")

    Catch sEx As SocketException
      Console.WriteLine(sEx.Message)

    End Try

  End Sub

End Class


Bob
0
 
indy500fanAuthor Commented:
Thanks Bob!  I'm going to try it out!!!
0
 
indy500fanAuthor Commented:
Bob,

Help me to understand what is going on here, please...

I created a form (Form1) and it has a button (Button 1)

When I click on on Button 1, it should call the WaitForData sub right?  Where do I assign the IP Address to listen to?

Eric
0
 
Bob LearnedCommented:
I have this code in my bag of tricks, but haven't completed the code to make it totally useful.  It's question like this that help make it better and better :)


To create a listener on port 6000 from any IP address:
Socket_Library.ListenToPort(6000)

To make this class useful, we'll need to change a few things:

(1) Remove the Shared from all the definitions
(2) Instantiate an instance where you need to use it (i.e. in the form).

     Private WithEvents sockets As New Socket_Library

(3) Change to Public Sub SendData
(4) Add event:

Public Event ReceiveData(ByVal sender As Object, e As SocketEventArgs)  

Public Class SocketEventArgs : Inherit System.EventArgs

   Public Data As String = String.Empty

   Public Sub New(ByVal newData As String)

      Me.Data = newData

   End Sub

End Class

(5) Raise the event in dataReceivedCallbackFunction after receivedData line:

    RaiseEvent DataReceived(New SocketEventArgs(Me, receivedData))

(6) Handle the event:

   Private Sub sockets_DataReceived(ByVal sender As Object, e As SocketEventArgs)

   End Sub

Bob
0
 
indy500fanAuthor Commented:
Thanks for posting the updates.  I started to freak a little bit... :)

Do you know how to get it to listen to a specific IP Address?

Say 10.10.0.42, on port 6000 for example?
0
 
Bob LearnedCommented:
Not exactly, but try this:

  Public Sub ListenToPort(ByVal portNumber As Integer, ByVal addressConnect As String)

    Dim addressSource As IPAddress = IPAddress.Parse(addressConnect)

    socketListener = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    Dim ipLocal As IPEndPoint = New IPEndPoint(addressSource, portNumber)

    Me.socketListener.Bind(ipLocal)
    Me.socketListener.Listen(1)

    Me.socketListener.BeginAccept(New AsyncCallback(AddressOf connectCallbackFunction), Nothing)

  End Sub 'ListenToPort'


Bob
0
 
indy500fanAuthor Commented:
Bob,

I think that'll work.  It's going to take me a while to work through this, but I appreciate your help!

Regards,
Eric.
0
 
Bob LearnedCommented:
Any problems, Eric?  Just checking in :)

Bob
0
 
indy500fanAuthor Commented:
Bob,

Yeah, lots of problems, but I know it's my inexperience, it's just taking a lot of time in the implementation.  The reason for the TCP communications is because, I have an operator program and a results program (and they HAVE to be on two different computers).  As the times and speeds are calculated in the operator program, they are inserted/updated in the database.  I wanted to send a command from the operator to the results screen (that looks at the database) to tell the results program to go out and look at the latest results in the database.  I am against a deadline (tomorrow morning), so for now, until I get the TCP communications going I have set a timer to execute a qry every second that, in effect will do the same thing.  So, for now, I am finishing both programs (using the timer for the results), and if I have time before Friday, I will begin working on the TCP stuff again.)   It stinks, but it will have to do if I can't get the TCP stuff working it will have to do.

Thank you sensai!

Eric
0
 
indy500fanAuthor Commented:
Bob,

Still working, but I bet it will be wednesday (May 18th) before I can give this my heart to this.  Sorry to let you down.

Eric
0
 
Bob LearnedCommented:
You're not letting me down.  If you forget about this it will just be cleaned up later (by me) ;)

Bob
0
 
indy500fanAuthor Commented:
Bob,

Don't worry, I haven't forgotten.

Talk to you soon.

Eric
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.