1
votes

I am not a software programmer but I have a task to create a TCP Server (a program that is listening on its network card interfaces for incoming data streams).

I have searched on the internet and I found that I can use two methods: Socket or TCPListener class.

I have created an example for the Socket class, but I was wondering how I can test it?

If another computer in the network sends some string data to the listener computer, then the message should be displayed.

Here is the example from Microsoft that I am using for the TCP server using a Socket:

    Public Shared Sub Main()
        ' Data buffer for incoming data.
        Dim data = nothing
        Dim bytes() As Byte = New [Byte](1024) {}
        Dim ipAddress As IPAddress = ipAddress.Any
        Dim localEndPoint As New IPEndPoint(ipAddress, 0)

        Dim intI As Integer = 0
        'Display the NIC interfaces from the listener
        For Each ipAddress In ipHostInfo.AddressList
            Console.WriteLine("The NIC are  {0}", ipHostInfo.AddressList(intI))
            intI += 1
        Next
           Console.WriteLine("You are listening on {0}",localEndPoint)
        ' Create a TCP/IP socket.
        Dim listener As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

        ' Bind the socket to the local endpoint and 
        ' listen for incoming connections.
        Try
            listener.Bind(localEndPoint)
            listener.Listen(200)
        Catch e As SocketException
            Console.WriteLine("An application is alreading using that combination of ip adress/port", e.ErrorCode.ToString)
        End Try

        ' Start listening for connections.
        While True
            Console.WriteLine("Waiting for a connection...")
            ' Program is suspended while waiting for an incoming connection.
            Dim handler As Socket = listener.Accept()
            data = Nothing
            ' An incoming connection needs to be processed.
            While True
                bytes = New Byte(1024) {}
                Dim bytesRec As Integer = handler.Receive(bytes)
                data += Encoding.ASCII.GetString(bytes, 0, bytesRec)
                Console.WriteLine("The string captured is  {0}", data)
                If data.IndexOf("something") > -1 Then
                    Exit While
                End If
            End While
            ' Show the data on the console.
            Console.WriteLine("Text received : {0}", data)
            ' Echo the data back to the client.
            Dim msg As Byte() = Encoding.ASCII.GetBytes(data)
            handler.Shutdown(SocketShutdown.Both)
            handler.Close()
        End While
    End Sub
End Class

Am I on the right lead? Thanks

Later Edit: I have used that code in a Console Application created with Visual Studio and I want to check the scenario when a device is sending some string message through the network. E.g: I have two devices :Computer A, computer B connected through LAN I have tried this command : telnet computerA port ( from computer B) but nothing is displayed in the TCP server running from computer A.

telnet 192.168.0.150 3232

I also made a TCP client for testing (derived from the Microsoft example):

Public Class SynchronousSocketClient

    Public Shared Sub Main()
        ' Data buffer for incoming data.
        Dim bytes(1024) As Byte

        Dim ipHostInfo As IPHostEntry = Dns.GetHostEntry(Dns.GetHostName())
        Dim ipAddress As IPAddress = ipHostInfo.AddressList(0)
        Dim remoteEP As New IPEndPoint(ipAddress, 11000)

        ' Create a TCP/IP socket.
        Dim sender As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

        ' Connect the socket to the remote endpoint.
        sender.Connect(remoteEP)

        Console.WriteLine("Socket connected to {0}", _
            sender.RemoteEndPoint.ToString())

        ' Encode the data string into a byte array.
        Dim msg As Byte() = _
            Encoding.ASCII.GetBytes("This is a test<EOF>")

        ' Send the data through the socket.
        Dim bytesSent As Integer = sender.Send(msg)

        ' Receive the response from the remote device.
        Dim bytesRec As Integer = sender.Receive(bytes)
        Console.WriteLine("Echoed test = {0}", _
            Encoding.ASCII.GetString(bytes, 0, bytesRec))

        ' Release the socket.
        sender.Shutdown(SocketShutdown.Both)
        sender.Close()
        Console.ReadLine()
    End Sub

End Class 'SynchronousSocketClient

But it does not work because of the PORT setting. If in the TCP Server I have "Dim localEndPoint As New IPEndPoint(ipAddress, 0)" then the client crashes, but if I change the port from any (0) to 11000 for example, the client works fine. Do you know why?

Later edit 2: Maybe I should have started with this question: Which method is recommended for my scope - asynchronous or synchronous method?

2
Yes, you are on the right path.Henrik

2 Answers

0
votes

Yes, you are on the right path.

The next thing to do is to introduce message detection since TCP is stream based and not message based like UDP. This means that TCP might decide to send two of your messages in the same packet (so that one socket.Recieve will get two messages) or that it will split up your message into two packets (thus requiring you to use two socket.Recieve to get it).

The two most common ways to create message detection is:

  • Create a fixed size header which includes message size
  • Create a delimiter which is appended to all messages.
0
votes

Your "server" isn't listening on a set port, so you'll need to pay attention to the "You are listening on" message that appears. Then, from another machine on the network, telnet the.ip.add.ress port. (This may require installing "telnet client", or enabling it in the Programs and Features stuff, or whatever.)

Side note...if you actually intend for this to be a server of some sort, you'll want to decide what port you want to use, so that other computers can find your service. Most people won't be able to read your screen to figure out where to connect. :)

As for your "client"...when you connect to another computer, you don't just "pick a port" (which is what a port number of 0 means in an endpoint). You need to know what port the server uses. (Reread what i said in the previous paragraph. A program running on another computer has no idea what port to use to connect to the server -- any server could be running on any port.) You need to pick a port number for the server (say, 11000...good as any, really) rather than letting it use port 0.