RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / user-557151

Sheud's questions

Martin Hope
Sheud
Asked: 2025-01-03 02:47:06 +0000 UTC

QUIC 客户端不想通过隧道连接

  • 6

我在 QUIC 上编写了这个基本服务器,它监听 2 个线程:

using System.Net;
using System.Net.Quic;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

namespace QuicServer
{
    class Program
    {
        static async Task Main(string[] args)
        {
            bool isRunning = true;
            X509Certificate2 serverCertificate = new X509Certificate2(@"C:\Users\sheud\source\repos\TESTQUICSERVER\certificate.pfx", "pswd");

            if (!QuicListener.IsSupported)
            {
                Console.WriteLine("QUIC is not supported, check for presence of libmsquic and support of TLS 1.3.");
                return;
            }

            var serverConnectionOptions = new QuicServerConnectionOptions
            {
                DefaultStreamErrorCode = 0x0A,
                DefaultCloseErrorCode = 0x0B,
                ServerAuthenticationOptions = new SslServerAuthenticationOptions
                {
                    ApplicationProtocols = new List<SslApplicationProtocol>
                    {
                        new SslApplicationProtocol("threadone"),
                        new SslApplicationProtocol("threadtwo")
                    },
                    ServerCertificate = serverCertificate
                }
            };

            var listener = await QuicListener.ListenAsync(new QuicListenerOptions
            {
                ListenEndPoint = new IPEndPoint(IPAddress.Any, 5555),
                ApplicationProtocols = new List<SslApplicationProtocol>
                {
                    new SslApplicationProtocol("threadone"),
                    new SslApplicationProtocol("threadtwo")
                },
                ConnectionOptionsCallback = (_, _, _) => ValueTask.FromResult(serverConnectionOptions)
            });

            Console.WriteLine("Server started...");

            while (isRunning)
            {
                var connection = await listener.AcceptConnectionAsync();
                Console.WriteLine($"Connection from {connection.RemoteEndPoint}");

                _ = Task.Run(async () =>
                {
                    try
                    {
                        var streamOne = await connection.AcceptInboundStreamAsync();
                        var streamTwo = await connection.AcceptInboundStreamAsync();

                        var readerOne = new StreamReader(streamOne);
                        var readerTwo = new StreamReader(streamTwo);

                        _ = Task.Run(async () =>
                        {
                            while (true)
                            {
                                var messageOne = await readerOne.ReadLineAsync();
                                if (messageOne == null) break;
                                Console.WriteLine($"Tunnel threadone received message: {messageOne}");
                            }
                        });

                        _ = Task.Run(async () =>
                        {
                            while (true)
                            {
                                var messageTwo = await readerTwo.ReadLineAsync();
                                if (messageTwo == null) break;
                                Console.WriteLine($"Tunnel threadtwo received message: {messageTwo}");
                            }
                        });

                        await Task.Delay(Timeout.Infinite);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Error: {ex.Message}");
                    }
                });
            }
        }
    }
}

还有一个客户端每秒向这两个线程发送消息:

using System.Net;
using System.Net.Quic;
using System.Net.Security;

namespace QuicClient
{
    class Program
    {
        static async Task Main(string[] args)
        {
            bool isRunning = true;

            if (!QuicConnection.IsSupported)
            {
                Console.WriteLine("QUIC is not supported, check for presence of libmsquic and support of TLS 1.3.");
                return;
            }

            var clientConnectionOptions = new QuicClientConnectionOptions
            {
                RemoteEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5555),
                DefaultStreamErrorCode = 0x0A,
                DefaultCloseErrorCode = 0x0B,
                MaxInboundUnidirectionalStreams = 10,
                MaxInboundBidirectionalStreams = 100,
                ClientAuthenticationOptions = new SslClientAuthenticationOptions
                {
                    ApplicationProtocols = new List<SslApplicationProtocol>
                    {
                        new SslApplicationProtocol("threadone"),
                        new SslApplicationProtocol("threadtwo")
                    },
                    TargetHost = "localhost",
                    RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
                }
            };

            QuicConnection? connection = null;
            try
            {
                connection = await QuicConnection.ConnectAsync(clientConnectionOptions);
                Console.WriteLine($"Connected {connection.LocalEndPoint} > {connection.RemoteEndPoint}");

                var streamOne = await connection.OpenOutboundStreamAsync(QuicStreamType.Bidirectional);
                var streamTwo = await connection.OpenOutboundStreamAsync(QuicStreamType.Bidirectional);

                var writerOne = new StreamWriter(streamOne);
                var writerTwo = new StreamWriter(streamTwo);

                while (isRunning)
                {
                    await writerOne.WriteLineAsync("message1");
                    await writerOne.FlushAsync();

                    await writerTwo.WriteLineAsync("message2");
                    await writerTwo.FlushAsync();

                    await Task.Delay(1000);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error connecting: {ex}");
            }

            if (connection != null)
            {
                await connection.CloseAsync(0x0C);
                await connection.DisposeAsync();
            }
        }
    }
}

这段代码有效,但是当我尝试不通过 localhost 而是通过隧道连接(我使用 ngrok,它支持 TLS 1.3)时,连接未建立。替换:

RemoteEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5555),

在

RemoteEndPoint = new DnsEndPoint("4.tcp.eu.ngrok.io", 10956),

我在 中设置了 TargetHost 参数4.tcp.eu.ngrok.io,但是当我连接时,我陷入沉默,几秒钟后,我收到一条错误消息,指出超时已过期。我怀疑证书存在一些问题,我使用以下方法创建了它:

New-SelfSignedCertificate -DnsName $env:computername,localhost -FriendlyName MsQuic-Test -KeyUsageProperty Sign -KeyUsage DigitalSignature -CertStoreLocation cert:\CurrentUser\My -HashAlgorithm SHA256 -Provider "Microsoft Software Key Storage Provider" -KeyExportPolicy Exportable

但我不确定问题出在证书上,我尝试通过 WireShark 监听端口10956,但没有看到任何内容,甚至没有任何连接尝试,所以我不确定问题出在证书上

c#
  • 1 个回答
  • 39 Views
Martin Hope
Sheud
Asked: 2024-09-17 03:56:36 +0000 UTC

更新图像中的源时出错

  • 5

我编写了以下代码来在 WPF 窗口中显示客户端发送的图像:

namespace ScreenStream
{
    public partial class MainWindow : Window
    {
        private TcpListener _listener;

        public MainWindow()
        {
            InitializeComponent();
            StartServer();
        }

        private async void StartServer()
        {
            _listener = new TcpListener(IPAddress.Any, 12345);
            _listener.Start();

            while (true)
            {
                var client = await _listener.AcceptTcpClientAsync();
                _ = Task.Run(() => HandleClient(client));
            }
        }

        private async Task HandleClient(TcpClient client)
        {
            using (var networkStream = client.GetStream())
            using (var memoryStream = new MemoryStream())
            {
                await networkStream.CopyToAsync(memoryStream);
                memoryStream.Position = 0;

                var bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = memoryStream;
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();

                Dispatcher.Invoke(() =>
                {
                    ScreenshotImage.Source = bitmapImage;
                });
            }
            client.Close();
        }

        protected override void OnClosed(EventArgs e)
        {
            _listener?.Stop();
            base.OnClosed(e);
        }
    }
}

问题是ScreenshotImage.Source = bitmapImage;它会抛出错误System.InvalidOperationException: 'The calling thread cannot access this object because a different thread owns it.'。

我尝试以不同的方式声明它纯粹是无意义的Dispatcher,例如:

this.Dispatcher.Invoke(() =>
{
    ScreenshotImage.Source = bitmapImage;
});

或者

Application.Current.Dispatcher.Invoke(() =>
{
    ScreenshotImage.Source = bitmapImage;
});

但结果总是相同的,原则上这并不奇怪,而且我对如何解决问题没有任何其他想法,我用谷歌搜索了它,他们写到的任何地方都可以通过简单地添加来修复错误Dispatcher.Invoke,但是对于出于某种原因它对我没有帮助

c#
  • 1 个回答
  • 36 Views

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5