Skip to main content
Tweeted twitter.com/StackCodeReview/status/1158256452978585600
Became Hot Network Question
corrected the name of the "TcpIsConnected"-property
Source Link
dadul96
  • 173
  • 2
  • 8

While writing this sample code I discovered a hidden bug. If you check the RemoteEndpointAddress exactly after the moment where a client connects to the server, then the RemoteEndpointAddress would be null (therefore I implemented the Sleep() in the first while-loop of the API-example-code). My first proposed solution would be to lock-in the "get" of the IsTcpConnectedTcpIsConnected-property as well as the inner part of the while-loop in the ListeningMethod(), but this would block the IsTcpConnectedTcpIsConnected-property forever since AcceptClient() is a blocking method. This means that I have to find a better way to fix this bug...

While writing this sample code I discovered a hidden bug. If you check the RemoteEndpointAddress exactly after the moment where a client connects to the server, then the RemoteEndpointAddress would be null (therefore I implemented the Sleep() in the first while-loop of the API-example-code). My first proposed solution would be to lock-in the "get" of the IsTcpConnected-property as well as the inner part of the while-loop in the ListeningMethod(), but this would block the IsTcpConnected-property forever since AcceptClient() is a blocking method. This means that I have to find a better way to fix this bug...

While writing this sample code I discovered a hidden bug. If you check the RemoteEndpointAddress exactly after the moment where a client connects to the server, then the RemoteEndpointAddress would be null (therefore I implemented the Sleep() in the first while-loop of the API-example-code). My first proposed solution would be to lock-in the "get" of the TcpIsConnected-property as well as the inner part of the while-loop in the ListeningMethod(), but this would block the TcpIsConnected-property forever since AcceptClient() is a blocking method. This means that I have to find a better way to fix this bug...

formatting
Source Link
dfhwze
  • 14.2k
  • 3
  • 40
  • 101

While writing this sample code I discovered a hidden bug. If you check the "RemoteEndpointAddress"RemoteEndpointAddress exactly after the moment where a client connects to the server, then the RemoteEndpointAddressRemoteEndpointAddress would be null (therefore I implemented the "Sleep()"Sleep() in the first while-loop of the API-example-code). My first proposed solution would be to lock-in the "get" of the IsTcpConnectedIsTcpConnected-property as well as the inner part of the while-loop in the ListeningMethod()ListeningMethod(), but this would block the IsTcpConnectedIsTcpConnected-property forever since AcceptClient()AcceptClient() is a blocking method. This means that I have to find a better way to fix this bug...

While writing this sample code I discovered a hidden bug. If you check the "RemoteEndpointAddress" exactly after the moment where a client connects to the server, then the RemoteEndpointAddress would be null (therefore I implemented the "Sleep()" in the first while-loop of the API-example-code). My first proposed solution would be to lock-in the "get" of the IsTcpConnected-property as well as the inner part of the while-loop in the ListeningMethod(), but this would block the IsTcpConnected-property forever since AcceptClient() is a blocking method. This means that I have to find a better way to fix this bug...

While writing this sample code I discovered a hidden bug. If you check the RemoteEndpointAddress exactly after the moment where a client connects to the server, then the RemoteEndpointAddress would be null (therefore I implemented the Sleep() in the first while-loop of the API-example-code). My first proposed solution would be to lock-in the "get" of the IsTcpConnected-property as well as the inner part of the while-loop in the ListeningMethod(), but this would block the IsTcpConnected-property forever since AcceptClient() is a blocking method. This means that I have to find a better way to fix this bug...

Added information, as suggested in the comments.
Source Link
dadul96
  • 173
  • 2
  • 8

EDIT (as VisualMelon suggested):

The API has following interfaces:

methods:

  • bool Connect(string IP, int port) - returns true, if the client could connect to the server
  • bool Disconnect() - returns true, if all connections could be successfully closed
  • bool Listen(int port) - returns true, if the listener could be successfully started
  • bool Send(string sendString) - returns true, if the string could be successfully sent
  • string GetReceivedString() - returns the received string or an empty string, if nothing got received
  • void Dispose() - runs Disconnect() and disposes everything

properties:

  • RemoteEndpointAddress - address of the client that connected to the server
  • TcpIsConnected - is true, if a TCP client is connected

A simple demonstration of a server implementation with my API:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TcpConnection_Lib;

namespace Tcp_Lib_Server_Tester
{
    class Program
    {
        static TcpConnection connection = new TcpConnection();
        static void Main(string[] args)
        {
            connection.Listen(23); //starts a TCP listener on port 23

            while (!connection.TcpIsConnected)  //wait until a client connects
            {
                System.Threading.Thread.Sleep(100);
            }

            Console.Write("remote endpoint address: " + connection.RemoteEndpointAddress + Environment.NewLine); //prints the remote endpoint IP to the console

            bool successfulSendFlag = connection.Send("Hello world!"); //the server sends "Hello World!" to the remote peer and returns if the operation was successful

            if (successfulSendFlag)
            {
                Console.Write("String successfully sent." + Environment.NewLine);
            }
            else
            {
                Console.Write("String NOT successfully sent." + Environment.NewLine);
            }

            string tempReceiveString = "";

            while (tempReceiveString == "")
            {
                tempReceiveString = connection.GetReceivedString(); //returns the received string or an empty string, if nothing got received so far
            }

            Console.Write("Received: " + tempReceiveString + Environment.NewLine); //prints the received string to the console

            Console.ReadLine(); //keeps the console alive
        }
    }
}

(The client implementation would use "Connect(ip, port)" instead of "Listen(port)" and you could not print the "RemoteEndpointAddress".)

While writing this sample code I discovered a hidden bug. If you check the "RemoteEndpointAddress" exactly after the moment where a client connects to the server, then the RemoteEndpointAddress would be null (therefore I implemented the "Sleep()" in the first while-loop of the API-example-code). My first proposed solution would be to lock-in the "get" of the IsTcpConnected-property as well as the inner part of the while-loop in the ListeningMethod(), but this would block the IsTcpConnected-property forever since AcceptClient() is a blocking method. This means that I have to find a better way to fix this bug...

About the "lock-in" mechanism: I don't have any special use case other than preventing bugs (like the one mentioned above).

EDIT (as dfhwze suggested):

Main goals:

  • learn C# and OOP
  • learn about TCP
  • improve my coding style and architecture
  • create a universal library for any future projects that may come up, but nothing specific (theoretical uses: sending and receiving commands between single-board computers)
  • create a complete bugfree, well tested and good to read code

Single client instance:

Thank you for pointing that out, because I totally overlooked this limitation!

Server or Client:

This class should either be used as a client or as a server, but not both at the same time.

EDIT (as VisualMelon suggested):

The API has following interfaces:

methods:

  • bool Connect(string IP, int port) - returns true, if the client could connect to the server
  • bool Disconnect() - returns true, if all connections could be successfully closed
  • bool Listen(int port) - returns true, if the listener could be successfully started
  • bool Send(string sendString) - returns true, if the string could be successfully sent
  • string GetReceivedString() - returns the received string or an empty string, if nothing got received
  • void Dispose() - runs Disconnect() and disposes everything

properties:

  • RemoteEndpointAddress - address of the client that connected to the server
  • TcpIsConnected - is true, if a TCP client is connected

A simple demonstration of a server implementation with my API:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TcpConnection_Lib;

namespace Tcp_Lib_Server_Tester
{
    class Program
    {
        static TcpConnection connection = new TcpConnection();
        static void Main(string[] args)
        {
            connection.Listen(23); //starts a TCP listener on port 23

            while (!connection.TcpIsConnected)  //wait until a client connects
            {
                System.Threading.Thread.Sleep(100);
            }

            Console.Write("remote endpoint address: " + connection.RemoteEndpointAddress + Environment.NewLine); //prints the remote endpoint IP to the console

            bool successfulSendFlag = connection.Send("Hello world!"); //the server sends "Hello World!" to the remote peer and returns if the operation was successful

            if (successfulSendFlag)
            {
                Console.Write("String successfully sent." + Environment.NewLine);
            }
            else
            {
                Console.Write("String NOT successfully sent." + Environment.NewLine);
            }

            string tempReceiveString = "";

            while (tempReceiveString == "")
            {
                tempReceiveString = connection.GetReceivedString(); //returns the received string or an empty string, if nothing got received so far
            }

            Console.Write("Received: " + tempReceiveString + Environment.NewLine); //prints the received string to the console

            Console.ReadLine(); //keeps the console alive
        }
    }
}

(The client implementation would use "Connect(ip, port)" instead of "Listen(port)" and you could not print the "RemoteEndpointAddress".)

While writing this sample code I discovered a hidden bug. If you check the "RemoteEndpointAddress" exactly after the moment where a client connects to the server, then the RemoteEndpointAddress would be null (therefore I implemented the "Sleep()" in the first while-loop of the API-example-code). My first proposed solution would be to lock-in the "get" of the IsTcpConnected-property as well as the inner part of the while-loop in the ListeningMethod(), but this would block the IsTcpConnected-property forever since AcceptClient() is a blocking method. This means that I have to find a better way to fix this bug...

About the "lock-in" mechanism: I don't have any special use case other than preventing bugs (like the one mentioned above).

EDIT (as dfhwze suggested):

Main goals:

  • learn C# and OOP
  • learn about TCP
  • improve my coding style and architecture
  • create a universal library for any future projects that may come up, but nothing specific (theoretical uses: sending and receiving commands between single-board computers)
  • create a complete bugfree, well tested and good to read code

Single client instance:

Thank you for pointing that out, because I totally overlooked this limitation!

Server or Client:

This class should either be used as a client or as a server, but not both at the same time.

Source Link
dadul96
  • 173
  • 2
  • 8
Loading