Link to home
Start Free TrialLog in
Avatar of indy500fan
indy500fan

asked on

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
Avatar of cyberdevil67
cyberdevil67

Try this if you have any question let me know.

http://www.codeproject.com/vb/net/VbNetSendReceiveTcp.asp
Avatar of indy500fan

ASKER

I'm downloading it now.  I'll be trying it shortly.
Avatar of Bob Learned
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
Thanks Bob!  I'm going to try it out!!!
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
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
ASKER CERTIFIED SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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?
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
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.
Any problems, Eric?  Just checking in :)

Bob
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
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
You're not letting me down.  If you forget about this it will just be cleaned up later (by me) ;)

Bob
Bob,

Don't worry, I haven't forgotten.

Talk to you soon.

Eric