c# - 让 HTTPClient 等待数据写入

标签 c# .net tcpclient

我想通过 tcp 将数据发送到特定的 ip\port 我写了一个示例,应该向那里发送一些字符串:

internal class TcpSender : BaseDataSender
{
    public TcpSender(Settings settings) : base(settings)
    {
    }

    public async override Task SendDataAsync(string data)
    {
        Guard.ArgumentNotNullOrEmptyString(data, nameof(data));

        byte[] sendData = Encoding.UTF8.GetBytes(data);
        using (var client = new TcpClient(Settings.IpAddress, Settings.Port))
        using (var stream = client.GetStream())
        {
            await stream.WriteAsync(sendData, 0, sendData.Length);
        }
    }
}

这里的问题是我的流在 tcp 客户端发送所有数据之前就被处理掉了。我应该如何重写我的代码以等待所有数据被写入,然后才处理所有资源?谢谢

UPD:从控制台调用:

static void Main(string[] args)
{
    // here settings and date are gotten from args
    try
    {
        GenerateAndSendData(settings, date)
                .GetAwaiter()
                .GetResult();
    }
    catch (Exception e)
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine(e);
    }
}

public static async Task GenerateAndSendData(Settings settings, DateTime date)
{
    var sender = new TcpSender(settings);
    await sender.SendDataAsync("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.");
}

Upd2:Echo 服务器代码(从一些 stackoverflow 问题中窃取):

class TcpEchoServer
{
    static TcpListener listen;
    static Thread serverthread;

    public static void Start()
    {
        listen = new TcpListener(System.Net.IPAddress.Parse("127.0.0.1"), 514);
        serverthread = new Thread(new ThreadStart(DoListen));
        serverthread.Start();
    }

    private static void DoListen()
    {
        // Listen
        listen.Start();
        Console.WriteLine("Server: Started server");

        while (true)
        {
            Console.WriteLine("Server: Waiting...");
            TcpClient client = listen.AcceptTcpClient();
            Console.WriteLine("Server: Waited");

            // New thread with client
            Thread clientThread = new Thread(new ParameterizedThreadStart(DoClient));
            clientThread.Start(client);
        }
    }

    private static void DoClient(object client)
    {
        // Read data
        TcpClient tClient = (TcpClient)client;

        Console.WriteLine("Client (Thread: {0}): Connected!", Thread.CurrentThread.ManagedThreadId);
        do
        {
            if (!tClient.Connected)
            {
                tClient.Close();
                Thread.CurrentThread.Abort();       // Kill thread.
            }

            if (tClient.Available > 0)
            {
                byte pByte = (byte)tClient.GetStream().ReadByte();
                Console.WriteLine("Client (Thread: {0}): Data {1}", Thread.CurrentThread.ManagedThreadId, pByte);
                tClient.GetStream().WriteByte(pByte);
            }

            // Pause
            Thread.Sleep(100);
        } while (true);
    }
}

最佳答案

最简单的部分是回显服务器运行缓慢,因为它在每次读取后暂停 100 毫秒。我想这是为了让您有机会看到发生了什么。

为什么你看不到所有数据,我不太确定,但我认为可能发生的情况是:

  • 当您的客户端执行离开 using block 时,流将被释放(感谢 Craig.Feied 在他的 answer 中指出执行在底层套接字完成物理传输之前继续进行数据)
  • 处理 NetworkStream 会导致它向底层 Socket 发出关闭命令>
  • 关闭让 Socket 有机会在它最终关闭之前完成所有缓冲数据的发送。引用:Graceful Shutdown, Linger Options, and Socket Closure
  • 请注意 NetworkStream 本身没有缓冲数据,因为它将所有写入直接传递到套接字。因此,即使在传输完成之前处理 NetworkStream,也不会丢失任何数据
  • 处于关闭状态的套接字可以完成现有请求但不会接受新请求。

因此,您的回显服务器从已经在进行的传输中接收数据(好的),但随后在连接上发出新的写入请求(不正常。)我怀疑此写入导致回显服务器提前退出而没有读取所有数据。要么:

  • 客户端关闭连接,因为它收到了它不期望的数据,或者
  • 回显服务器在 tClient.GetStream().WriteByte(pByte);
  • 上抛出未捕获的异常

检查它是否确实是上述任何一种应该很容易。

关于c# - 让 HTTPClient 等待数据写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52815825/

相关文章:

c# - 减慢 TCP/IP 接收速度

delphi - 通过 TCP\IP 使用 Indy 发送二进制数据,怎么样?

c# - 使用 CsQuery 遍历 dom

c# - WPF App.OnStartup() 在写入文件和 FileWatcher 时崩溃

c# - Web 客户端异常 : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel

c# - 在 Visual Studio 中给定一个类,如何找出包含它的 dll?

c# - 如何使用 C# 应用程序连接到 telnet 的 tcp 端口 23?

c# - 单声道/单声道开发 : Get solution version at runtime

c# - 在电子邮件中发送 HTML

.net - 如何处理 nservicebus 中的消息顺序?