gpt4 book ai didi

c# - 将 TCP StreamReader/StreamWriter 转换为 SSLStream

转载 作者:太空宇宙 更新时间:2023-11-03 12:57:13 25 4
gpt4 key购买 nike

这是我的代码:

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 Stream 有意见。这是我发现的:https://msdn.microsoft.com/en-us/library/system.net.security.sslstream(v=vs.110).aspx

我有几个问题:

  1. 我需要像网站证书一样购买 SSL 证书吗?
  2. 我可以生成自签名 SSL 证书吗?如果是这样并且需要它,你能告诉我如何实现它的任何引用吗?
  3. 是否可以将此 SSL 流附加到我的 StreamReader/StreamWriter?甚至需要它还是我必须重新制作整个连接/通信的东西?
  4. 当创建 SSLStream 时,服务器和客户端之间的整个通信将被加密,这样任何人都不能停留在中间并听/理解他们正在通信的内容?
  5. 如果我必须将证书文件附加到客户端,以便它可以成功建立到服务器的 SSL 连接,然后将该客户端发送给所有必须使用该客户端的人,这不会危及SSL 连接,因为我也向他们发送证书?

这就是我想问的。你能做的最好的事情是帮助我回答你的问题,如果可能的话,请把我必须应用的代码更改放在一起,以使 StreamReader/StreamWriter 在加密的 SSL 上工作。

最佳答案

  1. 你需要一个证书; makecert 可以工作,但默认情况下它不受信任,因此您需要向消费者提供自定义 RemoteCertificateValidationCallback,或者使用受信任的证书; Let's Encrypt那里可能会有用
  2. > makecertNew-SelfSignedCertificate
  3. SslStream 需要位于 NetworkStreamStreamReader 之间;坦率地说,让 StreamReader 在这里给你很多东西还不清楚——你可以在这里用 Streaam API 做任何事情;所以不用WriteLine,您可以手动编码,然后Write编码缓冲区;但是 - 没有理由您不能在两者中间重击 SslStream
  4. 是的
  5. 只有服务器需要证书(特别是,只有服务器需要证书的私钥); 一些相关的东西,称为“客户端证书”,用于验证客户端,但这是一个相关但不同的主题

举个例子,从 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 中的 NetworkStream。但同样:我真的认为您可以在此处删除StreamReader/StreamWriter,不会带来太多不便。

关于c# - 将 TCP StreamReader/StreamWriter 转换为 SSLStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49916299/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com