zoukankan      html  css  js  c++  java
  • c# tcp udp 的使用场景

    之前用tcp实现了一个案例(远程协助),后来我考虑用udp去实现它,于是又研究了下udp,我发现理论上udp可以做到,但是有一些问题不知道会不会有瓶颈

    我参照网上写了一个简单的示例如下

    服务端接收、发送数据

      int recv;
                byte[] data = new byte[1024];
                IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 8001);
                Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    
                //绑定网络地址
                newsock.Bind(ipep);
    
                Console.WriteLine("This is a Server, host name is {0}", Dns.GetHostName());
    
                //等待客户机连接
                Console.WriteLine("Waiting for a client");
    
                //得到客户机IP
                IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
                EndPoint Remote = (EndPoint)(sender);
                while (true)
                {
                    recv = newsock.ReceiveFrom(data, ref Remote);
                    newsock.SendTo(data, Remote);
                    Console.WriteLine("Message received from {0}: ", Remote.ToString());
                    Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
                }

    客户端发送、接收数据

           IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8001);
    
            //定义网络类型,数据连接类型和网络协议UDP
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            private void button1_Click(object sender, EventArgs e)
            {
                byte[] data = new byte[1024];
                string input, stringData;
    
                //构建TCP 服务器
    
               
    
                //设置服务IP,设置TCP端口号
              
                for (int i = 0; i<=0;i++ )
                {
                    string welcome =Guid.NewGuid().ToString();
                    data = Encoding.ASCII.GetBytes(welcome);
                    server.SendTo(data, data.Length, SocketFlags.None, ipep);
                }
    
                //Thread th = new Thread(receivedata);
                //th.Start();
               
               
            }
    
            public void receivedata()
            {
                byte[] data = new byte[1024];
                IPEndPoint sen = new IPEndPoint(IPAddress.Any, 0);
                EndPoint Remote = (EndPoint)sen;
                server.Bind(sen);
                data = new byte[1024];
                while (true)
                {
                    int recv = server.ReceiveFrom(data, ref Remote);
    
                    this.Invoke((EventHandler)delegate
                    {
                        listView1.Items.Add(new ListViewItem { Text = Encoding.ASCII.GetString(data, 0, recv) });
                    });
                  
                }
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                Thread th = new Thread(receivedata);
                th.Start();
            }

    于是问题出现了,因为我发现服务端udp是一个端口,一个线程(不知道怎么做多个端口映射,貌似也不可以),假如我做即时性要求很高数据量又大的应用,譬如远程协助或者语音聊天等,所有客户端都向服务端的一个端口发送数据,客户端稍有数量的话,会不会有接收瓶颈?

    于是我思考了下,假如我采用一个固定的端口用于采集客户端,采集到客户端后再给客户端分配一个端口,开辟一个线程用于监听这个客户端消息,这样的话我可以做到不同的客户端与服务器通信采用了彼此独立的端口,但是这样做和tcp协议又是很类似了,我就要改造udp,那么改造udp的成本要考虑进去,这是端口的问题,暂时不考虑端口,假设现在即时性要求降低了,只是文字聊天,服务端有一定的吞吐能力,仍然采用udp服务端做转发实现客户端与客户端的通信,那么服务端、客户端就要做心跳包,来检测连接是否断开,也要自己管理连接的状态。

    因此采用udp做即时应用 少不了的两个问题

    1.管理连接状态

    2.解决端口映射问题(随着客户端数量增加)

    当然还有其他的问题 譬如丢包、顺序等这里没有测试到

    所以tcp、udp的使用场景要视情况而定,你是否有足够能力去改造udp,让它变得完美,否则就稳妥的使用tcp吧

  • 相关阅读:
    代理模式
    spring aop
    mybatis从入门到精通(其他章节)
    mybatis从入门到精通(第6章)
    Java中Compareable和Comparator两种比较器的区别
    Java的equals方法的使用技巧
    Dubbo的配置过程,实现原理及架构详解
    什么是IPFS?IPFS与区块链有什么关系
    leetCode242 有效的字母异位词
    需要多个参数输入时-----------------考虑使用变种的Builder模式
  • 原文地址:https://www.cnblogs.com/njcxwz/p/9239632.html
Copyright © 2011-2022 走看看