我们知道.Net有UdpClient用于UDP的简单套接字使用。
来自MSDN:
如果您正在编写一个相对简单的应用程序并且不需要最高性能,请考虑使用TcpClient,TcpListener和UdpClient。这些类为Socket通信提供了一个更简单,用户友好的界面。
我想知道Raw Socket和UdpClient之间的性能差异有多大?我知道UdpClient是Udp的套接字包装器,它没有异步读/写。
还有别的吗?
由于
答案 0 :(得分:4)
正如文档所说,UdpClient / TcpClient是Socket类之上的一个瘦包装器。如果您只想发送/接收数据blob,那么这些类就很好。对于这种情况,Socket和UdpClient / TcpClient之间的性能没有差异。
但是,Socket确实以XXXAsync()方式提供了一种更快的IO方式。这些方法允许您执行非常快速的I / O,并且不会在TcpClient / UdpClient中公开。这就是文档所说的“性能差异” - 对于更快的性能,你必须深入研究Socket类并使用这些方法(XXXAsync)。
答案 1 :(得分:4)
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());
}
}
}
}
浪费了我几个小时的宝贵时间。
答案 2 :(得分:0)
UDP是一种无连接协议,它没有错误检查,它是与TCP的权衡,它比TCP更快。将TCP视为与TCP相比的“即发即忘”协议,其中完整性和校验和是TCP over UDP的额外开销。
无论使用何种协议,RawSocket都没有任何影响或差异。 RawSocket只是原始的,您必须放入相关的标头,例如源/目标IP地址,并确保标头符合相关协议。它与套接字的速度无关 - 这当然取决于您选择的协议。
希望这有帮助, 最好的祝福, 汤姆。