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.