好的,所以我在控制台应用程序中使用单线程制作了用于文件传输的服务器\客户端应用程序。每当我在同一个网络上同时运行客户端和服务器时,它都能完美运行,但每当我在互联网上尝试它时,它以每秒约 130000 字节的速度运行非常非常缓慢。客户端使用高速以太网连接,服务器使用无线连接。我正在使用端口转发将端口 54321 的请求发送到运行服务器的计算机。我正在使用 atcplistener
来侦听连接, atcpclient
接受连接, astreamreader
并附streamwriter
加到 anetworkstream
以发送/接收数据。关于为什么它可能这么慢的任何想法?顺便说一句,我知道事实上不是我的无线网络导致了延迟,我认为这是我的程序。这是我的代码:
服务器 :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace Server
{
class Program
{
static bool dontloop;
static string selectedfile;
static string[] filearray;
static bool authgood;
static bool goodexit;
static string version = "1.0.0";
static int timeout;
static bool multifile;
static bool ipblock;
static bool auth;
static string msg;
static string authpath;
static string banpath;
static int port;
static TcpListener tcp1;
static TcpClient tcp2;
static NetworkStream net;
static StreamReader sr;
static StreamWriter sw;
static BinaryReader br;
static BinaryWriter bw;
static long length;
static Int32 buffersize;
static byte[] buffer;
static FileStream mainfile;
static FileStream secondaryfile;
static string filelength;
static FileStream settingsfile;
static StreamReader settingsreader;
static string path;
static void Main(string[] args)
{
while (true)
{
try
{
Console.InputEncoding = UTF8Encoding.UTF8;
Console.OutputEncoding = UTF8Encoding.UTF8;
Console.Title = "File Server [Version : " + version + "] <SF>";
if (Console.BufferWidth > 59)
{
Console.WriteLine(@"
$$$$$$$$\ $$\ $$\
$$ _____|\__|$$ |
$$ | $$\ $$ | $$$$$$\
$$$$$\ $$ |$$ |$$ __$$\
$$ __| $$ |$$ |$$$$$$$$ |
$$ | $$ |$$ |$$ ____|
$$ | $$ |$$ |\$$$$$$$\
\__| \__|\__| \_______|
$$$$$$\
$$ __$$\
$$ / \__| $$$$$$\ $$$$$$\ $$\ $$\ $$$$$$\ $$$$$$\
\$$$$$$\ $$ __$$\ $$ __$$\\$$\ $$ |$$ __$$\ $$ __$$\
\____$$\ $$$$$$$$ |$$ | \__|\$$\$$ / $$$$$$$$ |$$ | \__|
$$\ $$ |$$ ____|$$ | \$$$ / $$ ____|$$ |
\$$$$$$ |\$$$$$$$\ $$ | \$ / \$$$$$$$\ $$ |
\______/ \_______|\__| \_/ \_______|\__|
");
}
else
{
Console.WriteLine("[FILE SERVER]");
}
settingsfile = new FileStream(Environment.CurrentDirectory.ToString() + @"\settings.cfg", FileMode.Open, FileAccess.Read);
settingsreader = new StreamReader(settingsfile);
string temp0 = settingsreader.ReadToEnd();
string[] settings = temp0.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
port = toint(settings.Skip(0).Take(1).First().Split('=').Last());
path = settings.Skip(1).Take(1).First().Split('=').Last();
authpath = settings.Skip(2).Take(1).First().Split('=').Last();
auth = Convert.ToBoolean(settings.Skip(3).Take(1).First().Split('=').Last());
banpath = settings.Skip(4).Take(1).First().Split('=').Last();
ipblock = Convert.ToBoolean(settings.Skip(5).Take(1).First().Split('=').Last());
timeout = toint(settings.Skip(6).Take(1).First().Split('=').Last());
multifile = Convert.ToBoolean(settings.Skip(7).Take(1).First().Split('=').Last());
settingsfile.Close();
settingsreader.Close();
tcp1 = new TcpListener(new IPEndPoint(IPAddress.Any, port));
tcp1.Start();
Console.WriteLine("Server started. Listening on '{0}'.", tcp1.LocalEndpoint.ToString());
tcp2 = tcp1.AcceptTcpClient();
tcp1.Server.Close();
net = tcp2.GetStream();
Console.WriteLine("Client '{0}' connected.", tcp2.Client.RemoteEndPoint.ToString().Split(':').First());
net.ReadTimeout = timeout;
net.WriteTimeout = timeout;
Console.WriteLine("Using '{0}' ms timeout.", timeout);
sr = new StreamReader(net);
sw = new StreamWriter(net);
string temp1 = sr.ReadLine();
if (temp1 != version)
{
throw new Exception("Client version '" + temp1 + "' does not match server version '" + version + "'!");
}
sw.WriteLine(net.ReadTimeout.ToString());
sw.Flush();
if (ipblock == true)
{
string clientip = tcp2.Client.RemoteEndPoint.ToString().Split(':').First();
FileStream banstream = File.OpenRead(banpath);
StreamReader banreader = new StreamReader(banstream);
while (banreader.EndOfStream == false)
{
if (banreader.ReadLine() == clientip)
{
throw new Exception("Client IP is banned!");
}
}
Console.WriteLine("Client '{0}' is not banned.", clientip);
}
if (auth == true)
{
sw.WriteLine("AUTH=TRUE");
sw.Flush();
Console.WriteLine("Waiting for client response...");
string creds = sr.ReadLine();
Console.WriteLine("Client is attempting login as '{0}'.", creds);
FileStream authstream = File.OpenRead(authpath);
StreamReader authreader = new StreamReader(authstream);
while (authreader.EndOfStream == false)
{
if (authreader.ReadLine() == creds)
{
authgood = true;
sw.WriteLine("ACCEPT");
flush();
Console.WriteLine("Client login successful.");
}
}
if (authgood == false)
{
sw.WriteLine("DENY");
flush();
throw new Exception("Client authentication failed!");
}
}
if (auth == false)
{
sw.WriteLine("AUTH=FALSE");
sw.Flush();
}
dontloop = false;
while (dontloop == false)
{
if (multifile == true)
{
sw.WriteLine("MULTIFILE=TRUE");
flush();
string temp3 = sr.ReadLine();
if (temp3 != "OK")
{
throw new Exception("Client response was incorrect! errcode=1.");
}
else
{
while (true)
{
filearray = Directory.GetFiles(path);
foreach (string s in filearray)
{
try
{
secondaryfile = File.OpenRead(s);
filelength = secondaryfile.Length.ToString();
secondaryfile.Close();
}
catch (Exception)
{
filelength = "(length unavailable)";
}
sw.WriteLine("{0} | {1} bytes.", s, filelength);
sw.Flush();
}
sw.WriteLine("STATUS=DONE");
sw.Flush();
Console.WriteLine("Waiting for client response...");
selectedfile = sr.ReadLine();
Console.WriteLine("Received client response.");
if (selectedfile != "0")
{
break;
}
else
{
Console.WriteLine("Client refreshed file list.");
}
}
int index = Convert.ToInt32(selectedfile) - 1;
string temp5 = filearray.Skip(index).Take(1).ToArray().First().ToString();
Console.WriteLine("Client selected '{0}'.", temp5);
mainfile = File.OpenRead(temp5);
length = mainfile.Length;
if (length < 65000)
{
buffersize = toint(length.ToString());
}
else
{
buffersize = 65000;
}
Console.WriteLine("Using '{0}' byte buffer.", buffersize.ToString());
}
}
if (multifile == false)
{
sw.WriteLine("MULTIFILE=FALSE");
flush();
string temp3 = sr.ReadLine();
if (temp3 != "OK")
{
throw new Exception("Client response was incorrect! errcode=2.");
}
else
{
try
{
secondaryfile = File.OpenRead(path);
filelength = secondaryfile.Length.ToString();
secondaryfile.Close();
}
catch (Exception)
{
filelength = "(length unavailable)";
}
sw.WriteLine("{0} | {1}", path, filelength);
sw.Flush();
Console.WriteLine("Waiting for client response...");
string temp4 = sr.ReadLine();
Console.WriteLine("Received client response.");
if (temp4 != "OK")
{
throw new Exception("Client response was incorrect! errcode=3.");
}
mainfile = File.OpenRead(path);
length = mainfile.Length;
if (length < 65000)
{
buffersize = toint(length.ToString());
}
else
{
buffersize = 65000;
}
Console.WriteLine("Using '{0}' byte buffer.", buffersize.ToString());
}
}
sw.WriteLine(mainfile.Length.ToString());
sw.Flush();
sw.WriteLine("READY?");
sw.Flush();
Console.WriteLine("Waiting for client response...");
string temp6 = sr.ReadLine();
if (temp6 != "YES")
{
throw new Exception("Client response was incorrect! errcode=4.");
}
br = new BinaryReader(mainfile);
bw = new BinaryWriter(net);
while (true)
{
try
{
string temp9 = sr.ReadLine();
if (temp9.ToString() == "DONE")
{
Console.WriteLine();
Console.WriteLine("Waiting for client response...");
string temp7 = sr.ReadLine();
if (temp7 == "CLOSE")
{
try
{
tcp2.Close();
if (tcp2.Connected == false)
{
throw new Exception();
}
}
catch (Exception)
{
goodexit = true;
dontloop = true;
break;
}
}
if (temp7 == "AGAIN")
{
Console.WriteLine("Client wants to download another file.");
mainfile.Close();
dontloop = false;
break;
}
}
long temp8 = Convert.ToInt64(temp9);
mainfile.Position = temp8;
if (length - temp8 >= buffersize)
{
buffersize = 65000;
}
if (length - temp8 < buffersize)
{
buffersize = toint((length - temp8).ToString());
}
buffer = new byte[buffersize];
buffer = br.ReadBytes(buffer.Length);
bw.Write(buffer);
string percent = Math.Round(((double)((double)temp8 / (double)length) * 100), 2, MidpointRounding.AwayFromZero).ToString();
if (percent == "100" && temp8 < length) { percent = "<100"; }
Console.Write("\rClient requested {0} / {1} bytes | {2}% done. ", temp8, length, percent);
bw.Flush();
}
catch (Exception err)
{
dontloop = true;
goodexit = false;
closeall();
Console.WriteLine();
Console.WriteLine(err.Message.ToString());
Console.WriteLine();
break;
}
}
if (goodexit == true)
{
closeall();
Console.WriteLine("Task complete.");
break;
}
}
}
catch (Exception err)
{
closeall();
Console.WriteLine();
Console.WriteLine(err.Message.ToString());
Console.WriteLine();
}
Console.WriteLine("Server restarting in 10 seconds.");
System.Threading.Thread.Sleep(10000);
}
}
static int toint(string string_)
{
int i = Convert.ToInt32(string_);
return i;
}
static void halfclose()
{
mainfile.Close();
bw.Close();
br.Close();
}
static void flush()
{
sw.Flush();
}
static void closeall()
{
try
{
br.Close();
}
catch { }
try
{
bw.Close();
}
catch { }
try
{
sr.Close();
}
catch { }
try
{
sw.Close();
}
catch { }
try
{
net.Close();
}
catch { }
try
{
tcp2.Close();
}
catch { }
try
{
tcp1.Server.Close();
}
catch { }
try
{
tcp1.Stop();
}
catch { }
}
}
}
客户端:可以在这里找到-> ftp://98.122.51.199/Program.cs
(正文的字符太多,上面的地址是我的 FTP 服务器)