The performance (or other) differences between raw Socket and UdpClient?

会有一股神秘感。 提交于 2019-12-24 08:23:00

问题


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


回答1:


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).




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/2320021/the-performance-or-other-differences-between-raw-socket-and-udpclient

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!