C# 将TCP StreamReader/StreamWriter转换为SSLStream

C# 将TCP StreamReader/StreamWriter转换为SSLStream,c#,ssl,unity3d,C#,Ssl,Unity3d,这是我的密码: public class ServerClient { public TcpClient tcp; public StreamReader streamReader; public StreamWriter streamWriter; public int accountId; public int connectionId; public ServerClient(TcpClient clientSocket) {

这是我的密码:

public class ServerClient
{
    public  TcpClient tcp;
    public StreamReader streamReader;
    public StreamWriter streamWriter;
    public int accountId;
    public int connectionId;
    public ServerClient(TcpClient clientSocket)
    {
        tcp = clientSocket;
        streamReader = new StreamReader(tcp.GetStream(), false);
        streamWriter = new StreamWriter(tcp.GetStream());
        clientSocket.NoDelay = true;
    }
}
下面是我监听数据的方式,在while循环中调用:

// Check for message from Client.
NetworkStream s = c.tcp.GetStream();
if (s.DataAvailable)
{
    string data = c.streamReader.ReadLine();

    if (data != null)
    {
        if (ValidateJSON(data))
        {
            OnIncomingData(c, data);
        }                            
    }

}
//continue;
以下是我如何检查客户端是否仍处于连接状态:

private bool IsConnected(TcpClient c)
{
    try
    {
        if (c != null && c.Client != null && c.Client.Connected)
        {
            if (c.Client.Poll(0, SelectMode.SelectRead))
            {
                return !(c.Client.Receive(new byte[1], SocketFlags.Peek) == 0);
            }

            return true;
        }
        else
        {
            return false;
        }
    }
    catch
    {
        return false;
    }
}
以下是我如何将数据发送到流中:

string JSonData = JsonConvert.SerializeObject(SendData);

c.streamWriter.WriteLine(JSonData);
c.streamWriter.Flush();
以下是我的客户端如何侦听消息:

public void ConnectToWorldServer()
{
    if (socketReady)
    {
        return;
    }
    //Default host and port values;
    string host = "127.0.0.1";
    int port = 8080;

    //ClientLoginServer ClientLoginServer = new ClientLoginServer();


    try
    {

        socket = new TcpClient(host, port);
        stream = socket.GetStream();
        socket.NoDelay = true;
        writer = new StreamWriter(stream);
        reader = new StreamReader(stream);
        socketReady = true;
        //Preserve the connection to worldserver thrue scenes
        UnityThread.executeInUpdate(() =>
        {
            DontDestroyOnLoad(worldserverConnection);
        });

        // Start listening for connections.
        while (true)
        {
            keepReading = true;

            while (keepReading)
            {
                keepReading = true;
                if (socketReady)
                {
                    if (stream.DataAvailable)
                    {
                        string data = reader.ReadLine();
                        if (data != null)
                        {
                            UnityThread.executeInUpdate(() =>
                            {
                                OnIncomingData(data);
                            });
                        }
                    }
                }
                System.Threading.Thread.Sleep(1);
            }
            System.Threading.Thread.Sleep(1);
        }
    }
    catch (Exception e)
    {
        Debug.Log("Socket error : " + e.Message);
    }

}
我有关于SSL流的红色消息。以下是我的发现:

我有几个问题:

  • 我是否需要购买SSL证书,如网站证书
  • 我可以生成自签名SSL证书吗?如果是这样的话,并且有必要的话,你能告诉我如何实现这一目标的参考资料吗
  • 是否可以将此SSL流附加到我的StreamReader/StreamWriter?这是必要的,还是我必须重新制作整个连接/沟通的东西
  • 当创建SSLStream时,服务器和客户端之间的整个通信将被加密,因此任何人都不能停留在这两者之间,听/理解他们在通信什么
  • 如果我必须将证书文件附加到客户端,以便它可以成功地建立到服务器的SSL连接,然后将该客户端发送给所有必须使用该客户端的人,那么在我向他们发送证书的同时,这是否会损害SSL连接的安全性 这就是我想要问的。您能做的最好的事情就是帮助我回答您的问题,如果可能的话,请将我必须应用的代码更改放在上面,以便使StreamReader/StreamWriter在加密SSL上工作

  • 你需要证书
    makecert
    可以工作,但默认情况下它不受信任,因此您需要向消费者提供自定义的
    RemoteCertificateValidationCallback
    ,或者使用受信任的证书;在那里可能有用
  • SslStream
    需要介于
    NetworkStream
    StreamReader
    之间;坦白地说,
    StreamReader
    在这里能给你带来什么并不清楚——你可以在这里用
    Streaam
    API做任何事情;因此,您不必使用
    WriteLine
    ,而是手动编码,然后
    写入编码的缓冲区;但是,没有理由,你不能在两个
  • 中间打“<代码> SSLFiels”。
  • 只有服务器需要证书(特别是,只有服务器需要证书的私钥);有一种称为“客户机证书”的相关内容用于验证客户机,但这是一个相关但不同的主题
  • 例如,从SE.Redis撕下的碎片,已经无法辨认;SE.Redis可选择加密,基本上是:

    Stream stream = // connect (get a NetworkStream)
    if (config.Ssl) {
        var ssl = new SslStream(stream, ... cert check callbacks, etc ...);
        ssl.AuthenticateAsClient(expectedHost, allowedSslProtocols);
        stream = ssl;
    }
    

    因此,如果您有类似的东西,您只需确保在将
    网络流
    包装到
    SslStream
    中后附加任何
    流阅读器
    /
    流编写器
    。但是,我想你可以在这里删除
    StreamReader
    /
    StreamWriter
    ,而不会给我带来太多不便。

    对我来说,
    试试。。抓住。。。return false
    是一种非常奇怪的“异常处理”方法。您能告诉我如何在SslStream中包装NetworkStream吗?所以你认为没有必要使用NetwrokStream。最好只使用SslStream,对吗?@TonyStark“你能告诉我如何在SslStream中包装NetworkStream吗”-点击刷新:)@TonyStark“所以你认为不需要NetworkStream”-我根本没有说-
    NetworkStream
    是使用
    SslStream
    的关键组件,因为
    SslStream
    需要一个
    ,而
    网络流
    使
    套接字
    看起来像
    谢谢@Marc grade。我不太清楚。我从未使用过Ssl蒸汽。如果我删除
    StreamReader/streamwriter
    我将如何从流中发送和读取消息?@TonyStark
    stream.read(…)
    stream.Write(…)
    -但是;无聊的。。。您现有的
    StreamReader
    /
    StreamWriter
    代码应该很好。。。如果你不熟悉那一部分,也许就别管它了