Giter Club home page Giter Club logo

tcpsharpr's Introduction

TcpSharpr

An easy to use C# networking library for .NET Standard/Core 2.0

What is TcpSharpr?

TcpSharpr is a small async-based networking library meant for easy internet/inter-process communication with other .NET applications. It allows you to call methods in other processes almost like you would call a method locally (see the example below).

How do I use this library?

With TcpSharpr, you register commands on your server/client for the other party to invoke. Commands can be invoked either synchronously or asynchronously. Use the respective methods for that to prevent issues.

How do I host a server?

Server server = new Server(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1805));
server.Start();

How do I create a client and connect to a server?

Client client = new Client(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1805));
await client.ConnectAsync();

How do I register a command for the other party to invoke

Synchronously

public int RemoteAddition(int a, int b) {
    return a + b;
}

server.CommandManager.RegisterCommand("AddNumbers", new Func<int, int, int>(RemoteAddition));

Asynchronously

public static async Task<string> DownloadHtml(string url) {
    return await new WebClient().DownloadStringTaskAsync(url);
}

server.CommandManager.RegisterAsyncCommand("DownloadHtml", new Func<string, Task<string>>(DownloadHtml));

How do I send a request?

var additionRequest = await client.SendRequestAsync("AddNumbers", 5, 10);
int result = await additionRequest.GetResultAsync<int>(); // result = 15

or if you don't care about the result...

await client.SendRequestAsync("AddNumbers", 5, 10);

What happens when theres an exception on the remote side?

When an exception occurs, some general data about it is sent back to the caller. On the caller end a RemoteExecutionException is thrown (it might be wrapped in several AggregateExceptions though). RemoteExceptionTypeName, RemoteExceptionMessage and RemoteExceptionStack contain the important information.

If everything is packet based, how do I transmit Streams?

TcpSharpr offers the ability to transmit Streams as part of remote command invocation. Take the following example: In this case I'd like to transmit a file from my PC to the server.

For the server to be able to receive the stream, it needs to have a command able of receiving that stream. Here's for example how to register this command:

server.CommandManager.RegisterAsyncCommand("StreamTransmission", new Func<SegmentedNetworkStream, Task>(StreamTransmission));

Note Any stream transmitted over the network requires the other side to be ready to receive it as a SegmentedNetworkStream. View below on how to read from it correctly.

Now that we have the command registered, let's send a file from our PC to that command on the server.

FileStream fileStream = new FileStream(@"C:\Users\timet\Desktop\dotnet-sdk-2.1.201-win-x64.exe", FileMode.Open);
var request = await client.SendAsync("StreamTransmission", fileStream);

This will start reading from the FileStream until the end and sending the chunks to the other party's SegmentedNetworkStream.

We may also use the returned NetworkRequest or NetworkMessage object to receive information over how far the transmission of all in this command invocation's Streams has progressed. You can find this information in NetworkMessage.NetworkTransmissionProgress or if you'd like it event based in NetworkMessage.OnNetworkTransmissionProgressChanged and NetworkMessage.OnNetworkTransmissionFinished.

So much for the sending part. But how do we read it on the server-side? Reading can be done like so:

private static async Task StreamTransmission(SegmentedNetworkStream segmentedNetworkStream) {
	while (!segmentedNetworkStream.DataComplete || segmentedNetworkStream.DataAvailable > 0) {
		byte[] buffer = new byte[1048576];
		
		// Wait until (partial) data has been transmitted and is ready to be used
		long dataAvailable = await segmentedNetworkStream.WaitUntilDataAvailable();
		int bytesRead = await segmentedNetworkStream.ReadAsync(buffer, 0, buffer.Length);
	}
}

SegmentedNetworkStream.WaitUntilDataAvailable() allows you to easily wait for the data to be received without blocking the execution thread. After this, you may do with the data what you want. SegmentedNetworkStream.DataComplete will become true once all data of that Stream is transmitted.

If you want to see how far you are through the Stream, use the SegmentedNetworkStream.PromisedLength property. It's value will be set before the very first transmission of that Stream.

Note If you transmit more than one Stream as a parameter, the Streams will be transmitted in order.

Note Returning a Stream from a command method is also supported. In this case you get the Stream the same way like this var responseStream = await request.GetResultAsync<SegmentedNetworkStream>();

Sending or receiving Streams inside a parameter object is not supported!

Full example

using System;
using System.Net;
using System.Threading.Tasks;

namespace TcpSharpr.Testing {
    class Program {
        static void Main(string[] args) {
            MainAsync().Wait();
        }

        static async Task MainAsync() {
            Server server = new Server(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1805));
            server.CommandManager.RegisterCommand("AddNumbers", new Func<int, int, int>(RemoteAddition));
            server.CommandManager.RegisterAsyncCommand("DownloadHtml", new Func<string, Task<string>>(DownloadHtml));
            server.Start();

            Client client = new Client(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1805));
            await client.ConnectAsync();

            int a = 5;
            int b = 7;

            Console.WriteLine($"> Server, what is {a} + {b}?");
            var additionRequest = await client.SendRequestAsync("AddNumbers", a, b);
            Console.WriteLine(">> Addition Result: " + await additionRequest.GetResultAsync<int>());

            string toDownloadUrl = "http://niceme.me/";

            Console.WriteLine($"> Server, download the html of {toDownloadUrl} for me please");
            var htmlRequest = await client.SendRequestAsync("DownloadHtml", toDownloadUrl);

            int c = 10;
            int d = 19;

            Console.WriteLine($"> Server, while you're downloading that html, can you please also tell me what's {c} + {d}");
            var additionRequest2 = await client.SendRequestAsync("AddNumbers", c, d);
            Console.WriteLine(">> Addition Result: " + await additionRequest2.GetResultAsync<int>());

            Console.WriteLine(">> Html Result:" + Environment.NewLine + await htmlRequest.GetResultAsync<string>());

            Console.ReadLine();
        }

        public static int RemoteAddition(int a, int b) {
            return a + b;
        }

        public static async Task<string> DownloadHtml(string url) {
            return await new WebClient().DownloadStringTaskAsync(url);
        }
    }
}

Contributions

https://github.com/MelvinGr for fixing various things, adding useful features and adding symmetric encryption support

tcpsharpr's People

Contributors

melvingr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

tcpsharpr's Issues

CPU usage 99% (Ubuntu)

I am getting a 99% CPU usage on my Ubuntu server, from the program using TcpSharpr.
The cause is still unknown; the only external libraries included in the project are TcpSharpr and Discord.NET, so it could be either one causing the issue. My program itself does almost nothing; just respond to some Discord callbacks, and TcpSharpr is being used in the localhost only. The program causing the issue is the server program; while the client program runs seamlessly.
https://i.ibb.co/DRK6tsd/unknown.png

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.