原始 Socket 和 UdpClient 之间的性能(或其他)差异?

发布于 2024-08-22 20:27:01 字数 311 浏览 6 评论 0原文

正如我们所知,.Net 有 UdpClient 用于 UDP 的简单套接字使用。

来自 MSDN:

如果您正在编写相对简单的应用程序并且不需要最大性能,请考虑使用 TcpClient、TcpListener 和 UdpClient。这些类为 Socket 通信提供了更简单、更用户友好的接口。

我想知道 Raw Socket 和 UdpClient 之间的性能差异有多大?我知道 UdpClient 是 Udp 套接字的包装器,它没有异步读/写功能。

还要别的吗?

谢谢

As we know .Net has UdpClient for simple Socket usage for UDP.

From MSDN:

If you are writing a relatively simple application and do not require maximum performance, consider using TcpClient, TcpListener, and UdpClient. These classes provide a simpler and more user-friendly interface to Socket communications.

I am wondering how much performance differences between Raw Socket and UdpClient? I know UdpClient is a wrapper of socket for Udp and it does not have asynchron read/write.

Anything else?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

戏蝶舞 2024-08-29 20:27:01

正如文档所说,UdpClient/TcpClient 是 Socket 类之上的一个薄包装器。如果您只想发送/接收数据块,那么这些类就很好。对于这种场景,Socket 和 UdpClient/TcpClient 之间的性能没有差异。

然而,Socket 确实以 XXXAsync() 方法的形式提供了一种更快的 IO 方法。这些方法允许您执行非常快的 I/O,并且不会在 TcpClient/UdpClient 中公开。这就是文档中“性能差异”的含义 - 为了更快的性能,您必须深入研究 Socket 类并使用这些方法(XXXAsync)。

As the docs say, UdpClient/TcpClient are a thin wrapper on top of Socket class. If all you want to do is send/receive blobs of data, then these classes are good. For this scenario, there is no difference in performance between Socket and UdpClient/TcpClient.

However, Socket does provide a faster way to do IO, in the form of XXXAsync() methods. These methods allow you to do very fast I/O, and are not exposed in TcpClient/UdpClient. That is what the docs mean by "perf difference" - it is that for faster perf, you will have to dig into Socket class and use these methods (XXXAsync).

鸠魁 2024-08-29 20:27:01

sendfile 并不快。


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Net.Cache;
using System.Threading;

namespace socket_sendfile
{
    delegate TimeSpan SendFileDelegate(Socket client, String filename, long fileSize);

    class Header
    {
        public long FileSize { get; set; }
        public int FileNumber { get; set; }

        public void Serialize(Stream stream)
        {
            byte[] buffer = BitConverter.GetBytes(this.FileNumber);
            stream.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(this.FileSize);
            stream.Write(buffer, 0, buffer.Length);
        }

        public static Header Deserialize(Stream stream)
        {
            Header header = new Header();

            byte[] buffer = new byte[4];
            int read = stream.Read(buffer, 0, buffer.Length);
            header.FileNumber = BitConverter.ToInt32(buffer, 0);

            buffer = new byte[sizeof(long)];
            read = stream.Read(buffer, 0, buffer.Length);
            header.FileSize = BitConverter.ToInt64(buffer, 0);
            return header;
        }
    }

    class Program
    {
        private Random rand = new Random();

        static void Main(string[] args)
        {
            Program prog = new Program();

            try
            {
                prog.StartServer();

                using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
                {
                    client.Bind(new IPEndPoint(0, 0));
                    client.Connect(new IPEndPoint(IPAddress.Loopback, 8080));

                    prog.Run(client, new SendFileDelegate(prog.SendFile1));

                    Console.WriteLine();
                    prog.Run(client, new SendFileDelegate(prog.SendFile2));
                }
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e);
            }
            Console.ReadKey();
        }

        void StartServer()
        {
            Thread serverThread = new Thread(new ThreadStart(this.Server));
            serverThread.Start();
        }

        void Run(Socket client, SendFileDelegate sendFileMethod)
        {
            foreach (long size in this.GetNextSize())
            {
                String filename = Path.GetTempFileName();

                this.CreateFile(filename, size);

                for (int i = 0; i  GetNextSize()
        {
            ulong[] sizes = { 1024, 4096, 8192, 16385, 65536, 1048576 };
            for (int i = 0; i  0)
                {
                    rand.NextBytes(buffer);
                    int writeSize = buffer.Length;
                    if (writeSize > (int)remaining)
                    {
                        writeSize = (int)remaining;
                    }

                    bw.Write(buffer, 0, writeSize);
                    remaining -= writeSize;
                }
            }
        }

        TimeSpan SendFile1(Socket client, String filename, long fileSize)
        {
            Stopwatch timer = new Stopwatch();

            //timer.Start();
            using (NetworkStream ns = new NetworkStream(client))
            {
                Header header = new Header();
                header.FileSize = fileSize;
                header.FileNumber = 1;

                // send the header
                header.Serialize(ns);

                using (FileStream fs = File.OpenRead(filename))
                {
                    //byte[] buffer = new byte[1024];
                    byte[] buffer = new byte[fileSize];
                    int read = fs.Read(buffer, 0, buffer.Length);
                    //Console.WriteLine("read = " + read);

                    while (read > 0)
                    {
                        timer.Start();
                        ns.Write(buffer, 0, read);
                        timer.Stop();
                        read = fs.Read(buffer, 0, buffer.Length);
                        //Console.WriteLine("read = " + read);
                    }
                }
            }

            //timer.Stop();

            return timer.Elapsed;
        }

        TimeSpan SendFile2(Socket client, String filename, long fileSize)
        {
            Stopwatch timer = new Stopwatch();

            //timer.Start();
            using (NetworkStream ns = new NetworkStream(client))
            {
                Header header = new Header();
                header.FileSize = fileSize;
                header.FileNumber = 1;

                byte[] headerBuffer = null;
                using (MemoryStream ms = new MemoryStream())
                {
                    header.Serialize(ms);
                    ms.Seek(0, SeekOrigin.Begin);
                    headerBuffer = ms.ToArray();
                }

                // send the header
                timer.Start();
                client.SendFile(filename, headerBuffer, null, TransmitFileOptions.UseDefaultWorkerThread);
                timer.Stop();
            }

            //timer.Stop();

            return timer.Elapsed;
        }

        void Server()
        {
            byte[] buffer = new byte[1024];
            try
            {
                TcpListener listener = new TcpListener(IPAddress.Loopback, 8080);
                listener.Start();
                using (TcpClient client = listener.AcceptTcpClient())
                using (NetworkStream ns = client.GetStream())
                {
                    bool hasData = true;
                    while (hasData)
                    {
                        // first get the header. Header has the file size.
                        Header header = Header.Deserialize(ns);

                        long remaining = header.FileSize;

                        while (remaining > 0)
                        {
                            int readSize = buffer.Length;
                            if ((long)readSize > remaining)
                                readSize = (int)remaining;

                            int read = ns.Read(buffer, 0, readSize);
                            remaining -= read;
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

        }
    }
}

浪费了我几个小时的宝贵时间。

sendfile is not faster.


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Net.Cache;
using System.Threading;

namespace socket_sendfile
{
    delegate TimeSpan SendFileDelegate(Socket client, String filename, long fileSize);

    class Header
    {
        public long FileSize { get; set; }
        public int FileNumber { get; set; }

        public void Serialize(Stream stream)
        {
            byte[] buffer = BitConverter.GetBytes(this.FileNumber);
            stream.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(this.FileSize);
            stream.Write(buffer, 0, buffer.Length);
        }

        public static Header Deserialize(Stream stream)
        {
            Header header = new Header();

            byte[] buffer = new byte[4];
            int read = stream.Read(buffer, 0, buffer.Length);
            header.FileNumber = BitConverter.ToInt32(buffer, 0);

            buffer = new byte[sizeof(long)];
            read = stream.Read(buffer, 0, buffer.Length);
            header.FileSize = BitConverter.ToInt64(buffer, 0);
            return header;
        }
    }

    class Program
    {
        private Random rand = new Random();

        static void Main(string[] args)
        {
            Program prog = new Program();

            try
            {
                prog.StartServer();

                using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
                {
                    client.Bind(new IPEndPoint(0, 0));
                    client.Connect(new IPEndPoint(IPAddress.Loopback, 8080));

                    prog.Run(client, new SendFileDelegate(prog.SendFile1));

                    Console.WriteLine();
                    prog.Run(client, new SendFileDelegate(prog.SendFile2));
                }
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e);
            }
            Console.ReadKey();
        }

        void StartServer()
        {
            Thread serverThread = new Thread(new ThreadStart(this.Server));
            serverThread.Start();
        }

        void Run(Socket client, SendFileDelegate sendFileMethod)
        {
            foreach (long size in this.GetNextSize())
            {
                String filename = Path.GetTempFileName();

                this.CreateFile(filename, size);

                for (int i = 0; i  GetNextSize()
        {
            ulong[] sizes = { 1024, 4096, 8192, 16385, 65536, 1048576 };
            for (int i = 0; i  0)
                {
                    rand.NextBytes(buffer);
                    int writeSize = buffer.Length;
                    if (writeSize > (int)remaining)
                    {
                        writeSize = (int)remaining;
                    }

                    bw.Write(buffer, 0, writeSize);
                    remaining -= writeSize;
                }
            }
        }

        TimeSpan SendFile1(Socket client, String filename, long fileSize)
        {
            Stopwatch timer = new Stopwatch();

            //timer.Start();
            using (NetworkStream ns = new NetworkStream(client))
            {
                Header header = new Header();
                header.FileSize = fileSize;
                header.FileNumber = 1;

                // send the header
                header.Serialize(ns);

                using (FileStream fs = File.OpenRead(filename))
                {
                    //byte[] buffer = new byte[1024];
                    byte[] buffer = new byte[fileSize];
                    int read = fs.Read(buffer, 0, buffer.Length);
                    //Console.WriteLine("read = " + read);

                    while (read > 0)
                    {
                        timer.Start();
                        ns.Write(buffer, 0, read);
                        timer.Stop();
                        read = fs.Read(buffer, 0, buffer.Length);
                        //Console.WriteLine("read = " + read);
                    }
                }
            }

            //timer.Stop();

            return timer.Elapsed;
        }

        TimeSpan SendFile2(Socket client, String filename, long fileSize)
        {
            Stopwatch timer = new Stopwatch();

            //timer.Start();
            using (NetworkStream ns = new NetworkStream(client))
            {
                Header header = new Header();
                header.FileSize = fileSize;
                header.FileNumber = 1;

                byte[] headerBuffer = null;
                using (MemoryStream ms = new MemoryStream())
                {
                    header.Serialize(ms);
                    ms.Seek(0, SeekOrigin.Begin);
                    headerBuffer = ms.ToArray();
                }

                // send the header
                timer.Start();
                client.SendFile(filename, headerBuffer, null, TransmitFileOptions.UseDefaultWorkerThread);
                timer.Stop();
            }

            //timer.Stop();

            return timer.Elapsed;
        }

        void Server()
        {
            byte[] buffer = new byte[1024];
            try
            {
                TcpListener listener = new TcpListener(IPAddress.Loopback, 8080);
                listener.Start();
                using (TcpClient client = listener.AcceptTcpClient())
                using (NetworkStream ns = client.GetStream())
                {
                    bool hasData = true;
                    while (hasData)
                    {
                        // first get the header. Header has the file size.
                        Header header = Header.Deserialize(ns);

                        long remaining = header.FileSize;

                        while (remaining > 0)
                        {
                            int readSize = buffer.Length;
                            if ((long)readSize > remaining)
                                readSize = (int)remaining;

                            int read = ns.Read(buffer, 0, readSize);
                            remaining -= read;
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

        }
    }
}

wasted couple hours of my precious time.

笛声青案梦长安 2024-08-29 20:27:01

UDP是一种无连接协议,具有零错误检查,它是与TCP的权衡,它比TCP更快。与 TCP 相比,UDP 是一种即发即忘协议,其中完整性和校验和是 TCP 相对于 UDP 的额外开销。

无论使用哪种协议,RawSocket 都没有任何影响或差异。 RawSocket 就是这样,原始的,你必须放入相关的标头,例如源/目标 IP 地址,并确保标头符合相关协议。它与套接字的速度无关 - 这当然取决于您选择的协议。

希望这有帮助,
此致,
汤姆.

UDP is a connectionless protocol which has zero error-checking, it is that, is the trade-off with TCP, it is faster than TCP. Think of UDP as a fire-and-forget protocol in comparison to TCP, where integrity and checksum is the additional overhead of the TCP over UDP.

RawSocket has no bearing or differences regardless of the protocol in use. A RawSocket is just that, raw, you have to put in the relevant headers such as the source/destination IP address, and to ensure that the headers conform to the relevant protocol. It has nothing to do with the speed of the socket - that will of course depend on the protocol you choose.

Hope this helps,
Best regards,
Tom.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文