繁体   English   中英

在 C# 中使用套接字和 tcp\\ip 在客户端服务器上工作

[英]Working on client server using sockets and tcp\ip in C#

我正在处理客户端-服务器数据接收。 我能够从作为我的仪表的服务器接收数据。 代码如下

listner = new TcpListener(new IPEndPoint(IPAddress.Any, port));
        Console.WriteLine("Listening...");
        listner.Start();
        while (true)
        {
            try
            {
                //---incoming client connected---
                TcpClient client = listner.AcceptTcpClient();

                //---get the incoming data through a network stream---
                NetworkStream nwStream = client.GetStream();
                byte[] buffer = new byte[client.ReceiveBufferSize];

                //---read incoming stream---
                int bytesRead = nwStream.Read(buffer, 0, client.ReceiveBufferSize);

                //---convert the data received into a string---
                string dataReceived = BitConverter.ToString(buffer, 0, bytesRead);
                //Encoding.ASCII.GetString(buffer, 0, bytesRead);
                //Console.WriteLine("Received : " + dataReceived);
                //MessageBox.Show("Data Received", dataReceived);
                //---write back the text to the client---
                //Console.WriteLine("Sending back : " + dataReceived);
                //nwStream.Write(buffer, 0, bytesRead);
                client.Close();
            }
            catch (Exception ex)
            {

            }

使用上面的代码我能够接收数据。 但我想执行以下操作

  1. 继续监听端口
  2. 在聆听时,我想向服务器(仪表)发送一些字节
  3. 发送一些数据后从服务器获取响应。

我知道有很多客户端 - 服务器教程,但它们有单独的服务器和客户端实现。 我只想处理客户端(我的软件)。 我也尝试过Asynchronous Server Socket Example

任何帮助将不胜感激。

您的服务器需要不断侦听来自客户端的连接。 每次获得连接时,您都会从操作系统获得一个新的TcpClient来处理该连接。 您从操作系统获得的TcpClient有时称为Child TcpClient,因为它是由侦听端口创建的。 但它在功能上与任何其他套接字相同。

使用 async/await 模式很容易实现这一点。

首先,您需要一个等待连接的侦听器,每次获得连接时,它都会将其传递给另一个处理子 TcpClient 的任务。 例如,

static async Task StartTcpServerAsync()
{
    var tcpListener = new TcpListener(new IPEndPoint(IPAddress.Any, 9999));
    tcpListener.Start();

    while (true)
    {
        var tcpClient = await tcpListener.AcceptTcpClientAsync();

        // Fire and forget the Child connection
        _ = StartChildTcpClientAsync(tcpClient);
    }
}

在上面的样板代码中,我们完全忘记了 ChildTcpClient 任务。 你可能想要也可能不想要这个。 如果你让任务完全自给自足(就像这个演示一样),那么主任务可能永远不需要知道它是否完成了。 但是如果你需要能够在 ChildTcpClient 任务和主任务之间提供反馈,那么你需要提供一些额外的代码来管理它,你首先要存储从StartChildTcpClientAsync(tcpClient);返回的任务StartChildTcpClientAsync(tcpClient); 某处,以便您可以观察它。 您可以在此处使用Task.Run() ,但在控制台应用程序中不需要。

现在你已经有了你的监听器任务,你需要一个 ChildTcpClient 任务,例如:

static async Task StartChildTcpClientAsync(TcpClient tcpClient)
{
    Console.WriteLine($"Connection received from: {tcpClient.Client.RemoteEndPoint.ToString()}");

    using var stream = tcpClient.GetStream();
    var buffer = new byte[1024];
    while (true)
    {
        var bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
        await stream.WriteAsync(buffer, 0, bytesRead);
    }
}

那是一个超级简单的 Tcp echo 客户端。 它没有流量控制,也没有错误处理,即使在客户端断开连接后,任务也会永远等待客户端发送一些数据。 此任务只是“等待”无穷大(或直到发生异常),因此您需要在此处添加一些代码来管理客户端,检查客户端是否仍处于连接状态等

要将它们整合在一起,您只需要一个像这样的 main:

static async Task Main(string[] args)
{
    await StartTcpServerAsync();
    // Will never exit unless tcpListener.AcceptTcpClientAsync();
    // throws an exception
}

就是这样,您有一个控制台应用程序,它等待无限数量的客户端连接,并且每次连接时它都有自己的任务来处理 IO。

暂无
暂无

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

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