【发布时间】:2011-03-30 08:22:28
【问题描述】:
我已经实现了一个异步函数来读取大型套接字数据,主要是文件将被传输。代码基于this question:
public class StateObject
{
public Socket workSocket = null;
public const int BUFFER_SIZE = 1024;
public byte[] buffer = new byte[BUFFER_SIZE];
public StringBuilder sb = new StringBuilder();
}
public static void Read_Callback(IAsyncResult ar)
{
StateObject so = (StateObject) ar.AsyncState;
Socket s = so.workSocket;
int read = s.EndReceive(ar);
if (read > 0)
{
so.sb.Append(Encoding.ASCII.GetString(so.buffer, 0, read));
if (read == StateObject.BUFFER_SIZE)
{
s.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0,
new AyncCallback(Async_Send_Receive.Read_Callback), so);
return;
}
}
if (so.sb.Length > 0)
{
//All of the data has been read, so displays it to the console
string strContent;
strContent = so.sb.ToString();
Console.WriteLine(String.Format("Read {0} byte from socket" +
"data = {1} ", strContent.Length, strContent));
}
s.Close();
}
在 stringbuilder 中捕获所有数据后,我将其解密并使用另一种方法将 base64 字符串转换为文件。将有多个套接字接收\发送文件,因此每个 workersocket 都有一个 ID。
现在是这种情况;我想要接收文件的一些状态。例如,进度条显示收到的金额和收到的总金额。 Read_Callback 方法使用递归调用来从套接字获取所有数据,这使我无法获得要接收的总量。有谁知道如何获得套接字必须接收的总金额?还是我唯一的选择是在传输数据之前将固定大小发送给侦听器?
如前所述,我的 stateobject 类包含一个 ID,用于标识数据所针对的套接字。在第一次连接时,程序将连接和接收到的信息存储在数组列表中。
为了获得已读取的字节数,我必须将状态报告给存储在 arraylist 中的已启动工作类之一。如果我想在递归调用期间执行此操作,我将如何执行此操作而不损失接收数据时的性能?
最后,应该使用哪个缓冲区大小?这应该是大多数情况下 1500 字节的 tcp 的 MTU 吗?
【问题讨论】:
-
有Code Review 提供有关良好做法的建议。
标签: c# sockets asynchronous