WCFサービスを使用して、tcpソケットを介してファイルとフォルダーを送信する小さなファイル転送アプリケーションがあります。クライアントからの転送操作(backgroundworker)をキャンセルしても、サーバーがまだフリーズして
いるという私の問題は、この例外が発生したと思われますが、クライアント側ではリスナー側になりますが、そうではありません。 Connectedになる
と、この例外を取得して処理する必要があります。これにより、ストリームとソケットを閉じて、別のタスクを受信できるようになります。client.Receive
An existing connection was forcibly closed by the remote host
false
false
クライアント側:
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
List<Job> Jobs = (List<Job>)e.Argument;
using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);
listener.Bind(endpoint);
listener.Listen(1);
client.ConnectToClient((IPEndPoint)listener.LocalEndPoint);
Socket socket = listener.Accept();
foreach (Job job in Jobs)
{
if (job.IsFile)
{
if (job.IsSend)
{ SendFile(socket, job, e); } //here i send a single file.
// else
// { ReceiveFile(socket, job, e); }
}
// else
// {
// if (job.IsSend)
// { SendDir(socket, job, e); }
// else
// { ReceiveDir(socket, job, e); }
// }
if (worker.CancellationPending)
{
e.Cancel = true;
socket.Dispose();
listener.Dispose();
Console.WriteLine(socket.Connected + " " + listener.Connected);
//it prints "FALSE FALSE"
return;
}
}
}
}
private void SendFile(Socket socket, Job job, DoWorkEventArgs e)
{
UpdateInfo(job.Name, job.Icon); //update GUI with file icon and name.
client.ReceiveFile((_File)job.Argument, bufferSize); //tell the client to start receiving
SendX(socket, ((_File)job.Argument).Path, e); //start sending..
}
private void SendX(Socket socket, string filePath, DoWorkEventArgs e)
{
using (Stream stream = File.OpenRead(filePath))
{
byte[] buffer = new byte[bufferSize];
long sum = 0;
int count = 0;
while (sum < stream.Length)
{
if (worker.CancellationPending)
{
e.Cancel = true;
return;
}
count = stream.Read(buffer, 0, buffer.Length);
socket.Send(buffer, 0, count, SocketFlags.None);
sum += count;
SumAll += count;
worker.ReportProgress((int)((sum * 100) / stream.Length));
}
}
}
サーバ側:
public void ConnectToClient(IPEndPoint endpoint)
{
if (client == null)
{
Thread th = new Thread(unused => ConnectTh(endpoint));
th.Start();
}
}
private void ConnectTh(IPEndPoint endpoint)
{
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(IPAddress.Parse("127.0.0.1"), endpoint.Port);
}
public void ReceiveFile(_File file, int bufferSize)
{
System.Threading.Thread th = new System.Threading.Thread(unused => ReceiveX(client, file.Name, file.Size, bufferSize));
th.Start();
}
private void ReceiveX(Socket client, string destPath, long size, int bufferSize)
{
try
{
using (Stream stream = File.Create(destPath))
{
byte[] buffer = new byte[bufferSize];
long sum = 0;
int count = 0;
while (sum < size)
{
int bytesToReceive = (int)Math.Min(buffer.Length, size - sum);
count = client.Receive(buffer, 0, bytesToReceive, SocketFlags.None);
stream.Write(buffer, 0, count);
sum += count;
}
}
}
catch
{
if (File.Exists(destPath))
File.Delete(destPath);
client.Dispose();
}
}