如何解决如何取消TCP文件传输c#
| 我有一个接收方和发送方客户端,几乎可以传输文件。到目前为止,这是我在接收器上得到的: Thread t1;
int flag = 0;
string receivedPath;
public delegate void MyDelegate(string s);
int bytesRead = 0;
bool endReceive = false;
public Form1()
{
t1 = new Thread(new ThreadStart(StartListening));
t1.Start();
InitializeComponent();
}
public class StateObject
{
// Client socket.
public Socket workSocket = null;
public const int BufferSize = 1024*100;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
}
public static ManualResetEvent allDone = new ManualResetEvent(false);
public void StartListening()
{
byte[] bytes = new Byte[1024*1000];
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any,9050);
Socket listener = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
try
{
listener.Bind(ipEnd);
listener.Listen(100);
while (true)
{
allDone.Reset();
listener.BeginAccept(new AsyncCallback(AcceptCallback),listener);
allDone.WaitOne();
if (endReceive)
{
listener.Disconnect(true);
}
}
}
catch (Exception ex)
{
}
}
public void AcceptCallback(IAsyncResult ar)
{
allDone.Set();
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer,StateObject.BufferSize,new AsyncCallback(ReadCallback),state);
flag = 0;
}
public void ReadCallback(IAsyncResult ar)
{
int fileNameLen = 1;
String content = String.Empty;
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
try
{
bytesRead= handler.EndReceive(ar);
}
catch (SocketException x)
{
MessageBox.Show(\"File Transfer was cancelled\");
Invoke(new MyDelegate(LabelWriter),new object[] { \"Waiting for connections\" });
if (File.Exists(receivedPath))
{
File.Delete(receivedPath);
return;
}
}
if (endReceive)
{
handler.Disconnect(true);
if (File.Exists(receivedPath))
{
File.Delete(receivedPath);
}
return;
}
if (bytesRead > 0)
{
if (flag == 0)
{
fileNameLen = BitConverter.ToInt32(state.buffer,0);
string fileName = Encoding.UTF8.GetString(state.buffer,4,fileNameLen);
receivedPath = fileName;
Invoke(new MyDelegate(LabelWriter),new object[] { \"Receiving File: \" + fileName });
flag++;
}
if (flag >= 1)
{
BinaryWriter writer = new BinaryWriter(File.Open(receivedPath,FileMode.Append));
if (flag == 1)
{
writer.Write(state.buffer,4 + fileNameLen,bytesRead - (4 + fileNameLen));
flag++;
ReleaseMemory();
}
else
writer.Write(state.buffer,bytesRead);
writer.Close();
try
{
handler.BeginReceive(state.buffer,state);
}
catch (SocketException exc)
{
MessageBox.Show(\"File Transfer was cancelled\");
Invoke(new MyDelegate(LabelWriter),new object[] { \"Waiting for connections\" });
if (File.Exists(receivedPath))
{
File.Delete(receivedPath);
return;
}
}
}
}
else
Invoke(new MyDelegate(LabelWriter),new object[] {\"Data Received\"});
}
我要实现的是在转移过程中取消转移的能力。我想到的是将布尔\“ EndReceive \”设置为false,并且每次调用ReadCallBack方法时,都会检查EndReceive。如果不正确,请断开插座。它可以阻止文件的接收,但是发件人应用程序只会冻结。这基本上是我发送的方式:
while (true)
{
int index = 0;
while (index < fs.Length)
{
int bytesRead = fs.Read(fileData,index,fileData.Length - index);
if (bytesRead == 0)
{
break;
}
index += bytesRead;
}
if (index != 0)
{
try
{
clientSock.Send(fileData,SocketFlags.None);
}
catch (Exception sexc)
{
MessageBox.Show(\"Transfer Cancelled\");
return;
}
ReleaseMemory();
if ((progressBar1.Value + (1024 * 1000)) > fs.Length)
{
progressBar1.Value += ((int)fs.Length - progressBar1.Value);
}
else
progressBar1.Value += (1024 * 1000);
lblSent.Text = index.ToString();
}
if (index != fileData.Length)
{
ReleaseMemory();
progressBar1.Value = 0;
clientSock.Close();
fs.Close();
break;
}
}
有什么想法吗?解决方法
我认为很难为正在执行的批量传输强制中断,并且仅使用TCP即可将其干净地关闭。如果您将块大小设为1024,并且在每次kB传输后,将快速ack或nack字节从接收方发送到发送方,该怎么办?表示传输将被中断的ack,表示继续的ack。
不幸的是,这需要对接收器/发送器进行全双工,并且要小心!即使它是异步IO,如果您计划和从同一套接字读写,也需要在单独的线程上调用BeginReceive和BeginSend。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。