【发布时间】:2012-04-13 17:15:10
【问题描述】:
我遇到了关于网络文件传输的问题。 当客户端超过 1 个时,Socket TCP/UDP 上传比本地 windows 复制慢。
我有一些 1Gbps 网络的 PC。
这是 Windows 复制案例。
一个客户端从服务器拷贝,最大上传速度100mbps左右。 (应该高于100mbps,路由有瓶颈。)
两个客户端从服务器复制,最大上传速度约为200mbps。
三个客户端从服务器复制,最大上传速度约300mbps。
这里是 Socket 案例。
一个客户端从服务器下载,最大上传速度100mbps左右。
两个客户端从服务器下载,最大上传速度约100mbps。
三个客户端从服务器下载,最大上传速度约100mbps。
如你所见,随着客户端数量的增加,socket服务器的上传速度并没有增加。
我们制作了一个简单的程序来测试这个问题。它遇到了同样的问题。 这只是非常简单的发送和接收调用。 请检查代码。
class Program
{
static List<TcpClient> sessions = new List<TcpClient>();
static void Main(string[] args)
{
bool isServer = false;
Console.WriteLine("Run as a server? (Y/N)");
string answer = Console.ReadLine();
if (answer.ToUpper().StartsWith("Y")) isServer = true;
if (isServer)
{
TcpListener listener = new TcpListener(IPAddress.Any, 13579);
Console.WriteLine("Listening at: " + ((IPEndPoint)listener.LocalEndpoint).ToString());
listener.Start();
Thread workerThread = new Thread(() =>
{
while (true)
{
lock (sessions)
{
foreach (var client in sessions)
{
if (client.Available > 0)
{
byte[] buffer = new byte[client.Available];
int length = client.Client.Receive(buffer);
string filePath = Encoding.UTF8.GetString(buffer, 0, length);
if (File.Exists(filePath))
{
foreach (var receiver in sessions)
receiver.Client.SendFile(filePath, null, null, TransmitFileOptions.UseKernelApc | TransmitFileOptions.WriteBehind);
}
}
}
}
Thread.Sleep(200);
}
});
workerThread.IsBackground = true;
workerThread.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();
lock (sessions)
{
sessions.Add(client);
}
}
}
else
{
Console.WriteLine("Enter the server IP:");
string ipAddress = Console.ReadLine();
TcpClient client = new TcpClient(ipAddress, 13579);
Console.WriteLine("Enter the file path on remote server:");
string remoteFilePath = Console.ReadLine();
if(remoteFilePath != "")
client.Client.Send(Encoding.UTF8.GetBytes(remoteFilePath));
byte[] recvBuffer = new byte[32768];
while(true)
{
try
{
client.Client.Receive(recvBuffer, 32768, SocketFlags.None);
}
catch (SocketException e)
{
Console.WriteLine("Transfer interrupted: {0}", e.Message);
break;
}
}
}
}
}
这阻碍了我们实现性能更好的套接字工具。 希望stackoverflow的家伙可以帮助我们。 谢谢高级。
【问题讨论】:
-
取决于您的客户端/服务器实现,我们对此一无所知。因此这个问题无法回答。
-
感谢快速回复,附上代码。
-
您是否在与使用 windows 复制测试的情况下在同一台机器上运行代码?
-
是的,与服务器相同的机器,相同的电脑。
-
我怀疑您的代码甚至可以正常工作,因此测量它没有多大意义。您是 (a) 假设您在第一次读取时准确且仅获得了一个完整的文件名,这是无效的,并且 (b) 忽略了所有其他读取的结果,这也是无效的。您还按顺序传输到所有客户端,Windows 实用程序可以在其中并行执行。
标签: c# sockets networking tcpclient