首页 新闻 会员 周边 捐助

C# 中如何正确使用 SslStream 读取 Socket

0
悬赏园豆:30 [待解决问题] 浏览: 62次

这是在园子维护的开源项目 EnyimMemcachedCore 中遇到的一个问题,当前的读取代码如下

public async Task ReadAsync(byte[] buffer, int offset, int count)
{
    int read = 0;
    int shouldRead = count;

    while (read < count)
    {
        int currentRead = _useSslStream
            ? await _sslStream.ReadAsync(buffer, offset, shouldRead).ConfigureAwait(false)
            : await _inputStream.ReadAsync(buffer, offset, shouldRead).ConfigureAwait(false);
        if (currentRead == count)
            break;
        if (currentRead < 1)
            throw new IOException("The socket seems to be disconnected");

        read += currentRead;
        offset += currentRead;
        shouldRead -= currentRead;
    }
}

目前有2个 issue 反馈不能正常读取:

dudu的主页 dudu | 高人七级 | 园豆:28244
提问于:2025-01-24 13:26
< > 人人可用的开源BI工具
分享
所有回答(2)
0

改为下面的读取代码进行验证

int currentRead = -1;
do
{
    currentRead = await _sslStream.ReadAsync(buffer, offset, shouldRead).ConfigureAwait(false);
}
while (currentRead != 0);
dudu | 园豆:28244 (高人七级) | 2025-01-24 21:06
0

在使用 SslStream 读取 Socket 数据时,确保正确处理 SSL/TLS 连接的特性是非常重要的。您提供的代码看起来基本上是正确的,但有几个地方可以改进,特别是针对 SSL 连接的处理。以下是一些建议和改进的代码示例:

改进建议

  1. 检查 SSL 连接状态

    • 在读取之前,确保 SSL 连接已经成功建立。
  2. 处理部分读取

    • SslStream.ReadAsync 可能会返回少于请求字节数的字节,因此需要在循环中处理。
  3. 增加超时和取消支持

    • 考虑使用 CancellationToken 来支持取消操作,以避免在网络问题时无限等待。
  4. 增强错误处理

    • 更详细的错误处理可以帮助识别问题。

改进后的代码示例

以下是根据上述建议改进后的 ReadAsync 方法:

public async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken = default)
{
    int read = 0;
    int shouldRead = count;

    while (read < count)
    {
        // 检查是否取消了操作
        cancellationToken.ThrowIfCancellationRequested();

        int currentRead;
        try
        {
            currentRead = _useSslStream
                ? await _sslStream.ReadAsync(buffer, offset + read, shouldRead, cancellationToken).ConfigureAwait(false)
                : await _inputStream.ReadAsync(buffer, offset + read, shouldRead, cancellationToken).ConfigureAwait(false);
        }
        catch (IOException ex)
        {
            // 处理 IOException,可能是连接问题
            throw new IOException("An error occurred while reading from the stream.", ex);
        }

        if (currentRead == 0)
        {
            // 连接已关闭
            throw new IOException("The socket seems to be disconnected");
        }

        read += currentRead;
        shouldRead -= currentRead;
    }
}

关键点说明

  • 取消支持:添加了 CancellationToken 支持,允许在需要时取消读取操作。
  • 读取偏移:在 ReadAsync 调用中,使用 offset + read 而不是 offset,确保从正确的位置开始读取。
  • 异常处理:捕获 IOException 并提供更具体的错误信息,帮助调试。

其他建议

  • 调试信息:在代码中添加日志记录,可以帮助您在出现问题时获取更多上下文信息。
  • SSL/TLS 配置:确保 SSL/TLS 设置正确,尤其是在与 AWS Memcached 集群连接时,可能需要特定的证书或协议支持。

结论

通过以上改进,您可以提高 SslStream 的读取稳定性和错误处理能力。如果问题仍然存在,请考虑检查网络连接、SSL 配置以及 AWS Memcached 的特定要求。如果有其他问题或需要进一步的帮助,请随时询问!

Technologyforgood | 园豆:7840 (大侠五级) | 2025-02-05 10:41
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册
Top