【问题标题】:C# tcp stream - is it possible to run stream without listener?C# tcp 流 - 是否可以在没有侦听器的情况下运行流?
【发布时间】:2015-05-14 09:27:05
【问题描述】:

我想编写一部分代码,在其中我开始使用 tcp 流发送包,但没有任何部分通过互联网接收它。 与此同时,我还希望有另一种方法可以随时连接到该特定流,并从连接的那一刻开始接收字节。 我想使用多播,但我发现无法通过 Internet 进行 有没有办法做到这一点?到目前为止,我只发现了一些信息,C# 中的 tcp 连接使用点对点的方式,所以我的情况听起来不可能实现,因为监听器必须始终处于活动状态才能初始化流媒体,我该如何绕过呢?

【问题讨论】:

  • 听起来你可能想要 UDP 而不是 TCP...
  • 感谢您的回答,我尝试管理的是在两个应用程序之间流式传输视频,第三个应用程序在中间。所以 app1 会将数据流式传输到中间的 app(我们称其为 app2),app2 会将这个流转发到 app3 上显示,但仅限于 app3 在线时。否则它会在 app2 上被收集/刷新,直到 app3 在线......此外,我希望有更多的应用程序,如 app1 和 app3,可以通过 app2 相互连接,是否可以有多个流中间一个应用转发的不同应用之间?
  • 使用 UDP。 TCP 链接需要 2 方。
  • 您的用例听起来像一个流服务器。您能否将已接受的客户保留在一个列表中,然后简单地将相同的数据写入所有客户?

标签: c# tcp stream tcpclient multicast


【解决方案1】:

编辑添加了一个简单的“代理”示例,该代理重新发布它收到的所有消息。

使用 UDP 并将您的数据包广播到可能会或可能不会在任何时间点侦听的端点。

或者使用消息队列,例如MSMQ、RabbitMQ 或0MQ

如果侦听服务长时间处于离线状态,那么 MSMQ 可能会成为问题,因为您的调度系统上的消息队列会导致可能会填满的积压。

如果您想使用 UDP 创建一些东西,这里有一些代码。

监听器(服务器):

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace UDPLISTENER
{
    class Program
    {
        static void Main(string[] args)
        {
            var port = 8750;
            var listener = new UdpClient(port);
            var group = new IPEndPoint(IPAddress.Any, port);

            Console.WriteLine("Listening for datagrams on port {0}", port);
            while(true)
            {
                var data = listener.Receive(ref group);
                Console.WriteLine("{0}: {1}", group.ToString(), Encoding.Default.GetString(data, 0, data.Length));
            }
        }
    }
}

代理(服务器和客户端):

sing System;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace UDPCLIENT
{
    class Program
    {
        static void Main(string[] args)
        {
            int listeningPort = 8749, dispatchPort = 8750;
            var listener = new UdpClient(listeningPort);
            var group = new IPEndPoint(IPAddress.Any, listeningPort);

            // Republish client
            var sender = new UdpClient("127.0.0.1", dispatchPort);

            Console.WriteLine("Listening for datagrams on port {0}", listeningPort);
            while (true)
            {
                var data = listener.Receive(ref group);
                Console.WriteLine("{0}: {1}", group.ToString(), Encoding.Default.GetString(data, 0, data.Length));
                sender.Send(data, data.Length);
            }
        }
    }
}

发件人(客户):

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace UDPSENDER
{
    class Program
    {
        static void Main(string[] args)
        {
            var sender = new UdpClient("127.0.0.1", 8749);

            while (true)
            {
                Console.WriteLine("Message: ");
                var data = Encoding.Default.GetBytes(Console.ReadLine());
                sender.Send(data, data.Length);
            }
        }
    }
}

根据您希望归档的内容,我推荐消息队列,它们提供了最大的灵活性。

但正如您所见,UDP 的工作方式与 TCP 略有不同。您不需要像 TCP 那样的握手,这意味着如果没有人在收听您的消息,它们就会消失,而发件人不会为此付出任何代价(网络仍然需要付出代价)。但是,如果弹出一个监听器,那么他们就会立即开始使用这些消息。请记住,没有 UDP 数据包可以保证传送,这既是福也是祸。

如果您希望确保消息得到保证,您需要实施自己的解决方案,一种方法是在数据报上设置计数器,如果缺少消息,侦听器会监视该数据报,然后它会请求重新发送该消息。

【讨论】:

  • 谢谢你的例子!我还有一个问题 - 是否可以引入第三个应用程序 - 位于客户端和听众之间的中间人?它只会从客户端接收字节并将其传输到侦听器......而且 - 是否可以引入通过中间的单个应用程序连接的许多客户端和许多侦听器(相对于 1 到 1)?
  • 听起来你想“代理”你的流是的,你可以这样做。如果您已经拥有有线协议,则可以将其移植到 UDP。您将需要弄清楚您希望如何路由网络流量,但您可以使用通道。 UDP 很好,你可以向它扔任何东西,它会正常工作,尝试这个例子并启动几个“客户端”并在“服务器”上启动它们,并注意它们只是工作,不需要监听 - 创建一个套接字- 并开始处理每个套接字流。
  • 听起来您正在寻找的解决方案的整体设计存在问题。可悲的是,你是回答这个问题的最佳人选。我可以以编程方式说,您可以使用 UDP 和 TCP 实现您所追求的目标。 UDP 听起来更适合您的问题。我会编写 3 个系统,一个流媒体,一个代理和一个查看器,然后使它们尽可能通用,并使用配置文件来驱动它们。使用我列出的示例,您可以看到侦听器可以轻松处理多个客户端,并且客户端并不关心侦听器是否活着。
  • 谢谢!我刚刚查看了您的编辑和中间人的代码,这确实有助于消除我的疑虑。我想要实现的是有这样的可能性:i.imgur.com/ObGQ5eF.png(对于糟糕的绘画技巧感到抱歉)-通过中间的人将每个客户与每个听众(1对1)联系起来,唯一的事情就是配置哪个客户端与哪个侦听器连接的可能性...使用上面的示例 - 是否可以运行多个客户端和多个侦听器并将它们中的每一个连接到一个代理?
  • 是的,您可以将服务器(代理)用作一种软件路由器,这会引入一些(不需要的?)延迟。在我的脑海中,您可以对 ip/port 进行编码或使用侦听器注册表并将其注册号作为前几个字节编码到数据报中。提取代理内部的信息,创建一个新的 UDPClient(将其缓存在字典中以便下次快速查找)并流式传输消息(删除编码的 ip 或注册表)。
【解决方案2】:

您可以创建一个派生自Stream 的新类,覆盖Write 方法,并在此处管理对tcp 客户端的写入。无论客户端是否连接,您都可以从代码中写入此流。当没有客户端连接时,数据将被简单地忽略。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 2014-03-20
    • 2011-10-30
    • 2019-03-30
    • 1970-01-01
    • 2021-07-29
    • 2011-07-24
    相关资源
    最近更新 更多