繁体   English   中英

TCP客户端PCL-如何从服务器发送和接收?

[英]TCP Client PCL - How to send and receive from server?

我在这里使用这个库: sockets-for-pcl

为什么使用这个库?

与xamarin android和WPF桌面进行通信。 (双向/双工通信)。

以下代码效果很好:

服务器:

var listenPort = 11000;
var listener = new TcpSocketListener();

// when we get connections, read byte-by-byte from the socket's read stream
listener.ConnectionReceived += async (sender, args) => 
{
    var client = args.SocketClient; 

    var bytesRead = -1;
    var buf = new byte[1];

    while (bytesRead != 0)
    {
        bytesRead = await args.SocketClient.ReadStream.ReadAsync(buf, 0, 1);
        if (bytesRead > 0)
            Debug.Write(buf[0]);
    }
};

// bind to the listen port across all interfaces
await listener.StartListeningAsync(listenPort);

客户:

var address = "127.0.0.1";
var port = 11000;
var r = new Random(); 

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

// we're connected!
for (int i = 0; i<5; i++)
{
    // write to the 'WriteStream' property of the socket client to send data
    var nextByte = (byte) r.Next(0,254);
    client.WriteStream.WriteByte(nextByte);
    await client.WriteStream.FlushAsync();

    // wait a little before sending the next bit of data
    await Task.Delay(TimeSpan.FromMilliseconds(500)); 
}

await client.DisconnectAsync();

我需要一个代码示例(双向/双工通信)。

客户端将数据发送到服务器,并从服务器接收数据。

查看此测试用例,然后查看TcpSocketClient_ShouldSendReceiveDataSimultaneously方法:

https://github.com/rdavisau/sockets-for-pcl/blob/dev/Sockets/Tests/Sockets.Tests/TcpSocketClientTests.cs

此方法演示了双向通信。 这有点令人困惑,因为它创建了两对连接,每个连接都有一个侦听器,因此它既充当客户端又充当服务器。 您可以轻松地将其拆分为单独的客户端和服务器代码。

实际上,建立连接后,客户端和服务器本质上是相同的。 可以是听众。 例如,在推送通知方案中,客户端是侦听器,而不是服务器。

他们首先设置服务器套接字,因为服务器必须等待连接才能成功进行客户端连接:

listener = new TcpSocketListener();
var tcs = new TaskCompletionSource<ITcpSocketClient>();         
await listener.StartListeningAsync(port);
listener.ConnectionReceived += (sender, args) => tcs.SetResult(args.SocketClient);

然后,客户端尝试使用其他套接字对象进行连接:

socket1 = new TcpSocketClient();
await socket1.ConnectAsync("127.0.0.1", port);

设置测试方法的方式有些混乱,因为它同时包含了服务器和客户端套接字,但是启动双工发送/接收的关键在于此处,您可以看到同时发生了发送和接收两个插座。 您可能不会以这种方式使用WhenAll ,因为他们只是为了完成测试而这样做,但是重点是您可以清楚地看到两个方向的两对发送/接收结果:

// let the sockets run for 2.5 seconds
var socketRunners =
  Task.WhenAll(
    Task.Run(() => sendAndReceive(socket1, sentToSocket2, recvdBySocket1, new CancellationTokenSource(TimeSpan.FromSeconds(2.5)).Token).ContinueWith(t=> Debug.WriteLine($"Socket 1 task completed: {t}"))),
    Task.Run(() => sendAndReceive(socket2, sentToSocket1, recvdBySocket2, new CancellationTokenSource(TimeSpan.FromSeconds(2.5)).Token).ContinueWith(t => Debug.WriteLine($"Socket 2 task completed: {t}")))
  );

sendAndReceive内部是发生魔术的地方。 请注意,它在上面并行运行了两次,一次用于socket1,一次用于socket2。 因此,两个套接字同时发送和接收。 sendAndReceive内部, sendAndReceive两个任务,一个正在不断地编写,另一个正在不断地读取(或接收)。 因此,您有两个sendAndReceive任务,其中每个任务开始两个任务(读和写)。 本质上并行发生4件事:套接字1读取,套接字1写入,套接字2读取,套接字2写入。

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[1000];
    while (!token.IsCancellationRequested)
    {
        var len = await socket.ReadStream.ReadAsync(buf, 0, buf.Length, token);
        recvd.AddRange(buf.Take(len));
    }
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM