我正在创建一个 HTTP 下载管理器,我在 c# 中使用纯套接字。
我不知道应该在每个网络流读取函数中读取多少 HTTP 数据。
如果我读到大约 1024 字节,那就没问题了。
但我想知道如何计算每次读取有多少可用数据?
这是我正在使用的代码
try
{
if (port == 443)
sslStream.Read(buffer, current_read, buffer.Length);
else
netStream.Read(buffer, current_read, buffer.Length);
}
catch (Exception ex)
{
Console.WriteLine("disconnected , can't read from stream");
return;
}
stream 的读函数会在 socket 中有数据时起作用。但没有提到缓冲区大小。我的意思是我应该将缓冲区长度设置为 tcp 协议最大数据包大小 (64KB)?
答案 0 :(得分:0)
HTTP 规范没有对帖子/获取施加特定的大小限制。它们通常会受到 Web 服务器或用于处理表单提交的编程技术的限制。
答案 1 :(得分:0)
TcpClient.Available
https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.available?view=net-5.0
获取已从网络接收到的可供读取的数据量。
Available 属性是一种确定数据是否排队等待读取的方法。如果有数据,则调用 Read 获取数据。可用数据是网络缓冲区中排队等待读取的数据总量。如果网络缓冲区中没有数据排队,Available 返回 0。
如果远程主机关闭或关闭连接,Available 可能会抛出 SocketException。如果收到 SocketException,请使用 SocketException.ErrorCode 获取具体的错误代码。获取此代码后,您可以参考Windows Sockets version 2 API 错误代码文档,了解错误的详细描述。
参考是: https://referencesource.microsoft.com/#system/net/system/net/Sockets/Socket.cs
第 345 行
这是对操作系统 dll 文件的另一个调用,我猜它们是 C 或 C++ 语言。
这是从 c# 中可用的实际调用的方法。 UnsafeNclNativeMethods.OSSOCK.ioctlsocket
/// <devdoc>
/// <para>
/// Gets the amount of data pending in the network's input buffer that can be
/// read from the socket.
/// </para>
/// </devdoc>
public int Available {
get {
if (CleanedUp) {
throw new ObjectDisposedException(this.GetType().FullName);
}
int argp = 0;
// This may throw ObjectDisposedException.
SocketError errorCode = UnsafeNclNativeMethods.OSSOCK.ioctlsocket(
m_Handle,
IoctlSocketConstants.FIONREAD,
ref argp);
GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::Available_get() UnsafeNclNativeMethods.OSSOCK.ioctlsocket returns errorCode:" + errorCode);
//
// if the native call fails we'll throw a SocketException
//
if (errorCode==SocketError.SocketError) {
//
// update our internal state after this socket error and throw
//
SocketException socketException = new SocketException();
UpdateStatusAfterSocketError(socketException);
if(s_LoggingEnabled)Logging.Exception(Logging.Sockets, this, "Available", socketException);
throw socketException;
}
return argp;
}
}