わかりましたので、コンソール アプリでシングル スレッドを使用してファイル転送用のサーバー/クライアント アプリを作成しました。クライアントとサーバーの両方を同じネットワーク上で実行するときはいつでも完全に動作しますが、インターネット経由で実行しようとすると、毎秒約 130000 バイトで非常に遅くなります。クライアントは高速イーサネット接続を使用しており、サーバーはワイヤレス接続を使用しています。ポート フォワーディングを使用して、サーバーを実行しているコンピューターにポート 54321 の要求を送信しています。を使用しtcplistener
て接続をリッスンし、 を使用して接続tcpclient
を受け入れ、 を に接続してstreamreader
データstreamwriter
をnetworkstream
送受信しています。なぜこんなに遅いのかについてのアイデアはありますか?ところで、遅れを引き起こしているのはワイヤレス ネットワークではなく、私のプログラムだと思います。これが私のコードです:
サーバー:
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 サーバーです)