Bidirectional Communication - Send and Receive string value correctly

2
Follow the server code:

int port = 11000/*PortGranter.GrantPort()*/;
TcpSocketListener listener = new TcpSocketListener();
var tcs = new TaskCompletionSource<ITcpSocketClient>();

await listener.StartListeningAsync(port);
listener.ConnectionReceived += (sender, args) => tcs.SetResult(args.SocketClient);

var socket2 = await tcs.Task;
await listener.StopListeningAsync();

// for five seconds, send and receive the data 
var sentToSocket1 = new List<byte>();
var sentToSocket2 = new List<byte>();
var recvdBySocket1 = new List<byte>();
var recvdBySocket2 = new List<byte>();

// send random data and keep track of it
// also keep track of what is received
Func<ITcpSocketClient, List<byte>, List<byte>, CancellationToken, Task> sendAndReceive =
    (socket, sent, recvd, token) =>
    {
        var r = new Random(socket.GetHashCode());
        var send = Task.Run(async () =>
        {
            var buf = new byte[1000];
            while (!token.IsCancellationRequested)
            {
                //r.NextBytes(buf);
                //sent.AddRange(buf);
                //await socket.WriteStream.WriteAsync(buf, 0, buf.Length, token);
                //await socket.WriteStream.FlushAsync(token);

                Byte[] data = Encoding.UTF8.GetBytes($"Amanhã não vou para escola, porque eu estou doente.<OAF>");
                await socket.WriteStream.WriteAsync(data, 0, data.Length, token);
                await socket.WriteStream.FlushAsync(token);
            }
        });

        var recv = Task.Run(async () =>
        {
            var buf = new byte[1000];
            while (!token.IsCancellationRequested)
            {
                var len = await socket.ReadStream.ReadAsync(buf, 0, buf.Length, token);
                recvd.AddRange(buf.Take(len));
            }
        });

        var innerTcs = new TaskCompletionSource<bool>();
        token.Register(() => innerTcs.SetResult(true));

        return innerTcs.Task;
    };

int port = 11000/*PortGranter.GrantPort()*/;
TcpSocketClient socket1 = new TcpSocketClient();
await socket1.ConnectAsync("192.168.0.153", port);

var sentToSocket1 = new List<byte>();
var sentToSocket2 = new List<byte>();
var recvdBySocket1 = new List<byte>();
var recvdBySocket2 = new List<byte>();

//enviar dados aleatórios e acompanhar isso também acompanhar o que é recebido
Func<ITcpSocketClient, List<byte>, List<byte>, CancellationToken, Task> sendAndReceive =
    (socket, sent, recvd, token) =>
    {
        var r = new Random(socket.GetHashCode());
        var send = Task.Run(async () =>
        {
            var buf = new byte[1000];
            while (!token.IsCancellationRequested)
            {
                r.NextBytes(buf);
                sent.AddRange(buf);
                await socket.WriteStream.WriteAsync(buf, 0, buf.Length, token);
                await socket.WriteStream.FlushAsync(token);
            }
        });

        var recv = Task.Run(async () =>
        {
            var buf = new byte[1];
            while (!token.IsCancellationRequested)
            {
                var len = await socket.ReadStream.ReadAsync(buf, 0, buf.Length, token);
                recvd.AddRange(buf.Take(len));
            }
        });

        var innerTcs = new TaskCompletionSource<bool>();
        token.Register(() => innerTcs.SetResult(true));

        return innerTcs.Task;
    };

string result = Encoding.UTF8.GetString(recvdBySocket1.ToArray());

In the variable result it returns several times the text Amanhã não vou para escola, porque eu estou doente.<OAF> .

Example of how it returns:

Amanhã não vou para escola, porque eu estou doente.<OAF>Amanhã não vou para escola, porque eu estou doente.<OAF>Amanhã não vou para escola, porque eu estou doente.<OAF>Amanhã não vou para escola, porque eu estou doente.<OAF>Amanhã não vou para escola, porque eu estou doente.<OAF>...

The library I use: link

Here is complete code similar to mine:

I just want to do something like this:

Client sends value to server after server sends to client and END.

It was the only example I found on the internet of how to do two-way communication using Portable Class Libraries .

Any solution?

    
asked by anonymous 16.03.2018 / 15:48

1 answer

2

As said in the comments by @Leandro the server will continue to write the message while there is no cancellation. I found it strange that there was no simple example as an echo server in Github so I did mine.

Server

static async Task Run()
{
    var listenPort = 11000;
    var listener = new TcpSocketListener();
    listener.ConnectionReceived += async (sender, args) =>
    {
        var client = args.SocketClient;
        var reader = new StreamReader(client.ReadStream);
        var data = await reader.ReadLineAsync() + "\n";
        var bytes = Encoding.UTF8.GetBytes(data);
        await client.WriteStream.WriteAsync(bytes, 0, bytes.Length);
        await client.WriteStream.FlushAsync();
    };

    await listener.StartListeningAsync(listenPort);
}

Customer

static async Task Run()
{
    var address = "127.0.0.1";
    var port = 11000;

    var client = new TcpSocketClient();
    await client.ConnectAsync(address, port);

    var bytes = Encoding.UTF8.GetBytes("Olá mundo\n");
    await client.WriteStream.WriteAsync(bytes, 0, bytes.Length);
    await client.WriteStream.FlushAsync();

    var reader = new StreamReader(client.ReadStream);
    var data = await reader.ReadLineAsync();
    Console.WriteLine(data);
}

In this case the client sends a message to the server, the server sends the message back. The client shows the message on the console and disconnects.

One important thing to note is that I chose to use ReadLineAsync of StreamReader . What this means is that either the messages sent by the server, or the messages sent by the client, have to end in \n .

I hope this is a more useful example for your goals than you've ever encountered.

    
16.03.2018 / 19:57