吃铜治白癜风吗 http://baidianfeng.39.net/a_wh/131029/4281177.html吃铜治白癜风吗 http://baidianfeng.39.net/a_wh/131029/4281177.html第四篇c#教程socket数据流的加密
接,的socket服务端程序:
namespaceConsoleApplicationSocket01
{
classProgram
{
staticvoidMain(string[]args)
{
Byte[]BytesOfReceived=newByte[];
SocketUnitySocketServer=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
IPAddressHostIpAddress=IPAddress.Parse(".0.0.1");
UnitySocketServer.Bind(newIPEndPoint(HostIpAddress,));
while(true){
if(UnitySocketServer.Receive(BytesOfReceived)0)
{
Console.Write(Encoding.UTF8.GetString(BytesOfReceived));
}
stringFrontString=Encoding.UTF8.GetString(BytesOfReceived);
FrontString=FrontString.Substring(0,4);
if(FrontString=="quit")
{
return;
}
}
}
}
}
客户端程序:
namespaceConsoleApplication02
{
classProgram
{
staticvoidMain(string[]args)
{
stringSendedString="HelloWorld!";
SocketUnitySocketSend=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
IPAddressHostIpAddress=IPAddress.Parse(".0.0.1");
UnitySocketSend.Bind(newIPEndPoint(HostIpAddress,));
while(true)
{
SendedString=Console.ReadLine();
UnitySocketSend.SendTo(Encoding.UTF8.GetBytes(SendedString),newIPEndPoint(HostIpAddress,));
}
}
}
}
接下来实现对socket数据流的加密。.net类库提供对数据流加密和解密的类,主要的命名空间有System.Security.Cryptography,主要的类有System.Security.Cryptography.CryptoStream,CryptoStream类接受一个普通流,然后对其加密,并返回一个流。
一、先添加命名空间:
UsingSystem.Security.Cryptography;
然后再程序中添加CryptoStream变量。由于每次收发都需要加密,CryptoStream变量应添加在发送函数之前:
usingSystem.Security.Cryptography;
namespaceConsoleApplication02
{
classProgram
{
staticvoidMain(string[]args)
{
stringSendedString="HelloWorld!";
SocketUnitySocketSend=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
IPAddressHostIpAddress=IPAddress.Parse(".0.0.1");
UnitySocketSend.Bind(newIPEndPoint(HostIpAddress,));
while(true)
{
SendedString=Console.ReadLine();
CryptoStreamCStream=newCryptoStream();
UnitySocketSend.SendTo(Encoding.UTF8.GetBytes(SendedString),newIPEndPoint(HostIpAddress,));
}
}
}
}
上面的代码存在问题,需要修正。
二、CryptoStream的构造函数接收三个参数,第一个参数是普通的流,第二个参数是加密的算法,第三个参数是CryptoStream流的读写模式。并且在CryptoStream流上的写会直接写入普通的流。
流并不是底层概念,它是上层概念,很多开发软件包都将对计算机的底层资源的操作进行了抽象和统一,把对磁盘、文档、内存的读写操作统一为流,对文档有文档流FileStream,对内存有内存流MemoryStream。
先添加命名空间System.IO,它包含有流的诸多类:
usingSystem.IO;
然后构造一个空的MemoryStream,使用MemoryStream()构造函数初始化的空流具有可读、可写、可变大小的特性:
namespaceConsoleApplication02
{
classProgram
{
staticvoidMain(string[]args)
{
stringSendedString="HelloWorld!";
SocketUnitySocketSend=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
IPAddressHostIpAddress=IPAddress.Parse(".0.0.1");
UnitySocketSend.Bind(newIPEndPoint(HostIpAddress,));
while(true)
{
SendedString=Console.ReadLine();
MemoryStreamStreamSendString=newMemoryStream();
CryptoStreamCStream=newCryptoStream();
UnitySocketSend.SendTo(SendedString,newIPEndPoint(HostIpAddress,));
}
}
}
}
三、继续修正,添加加密算法Rijndael,并初始化加密流CryptoStream:
在CryptoStream的构造函数中要传入MemoryStream流和加密算法
namespaceConsoleApplication02
{
classProgram
{
staticvoidMain(string[]args)
{
stringSendedString="HelloWorld!";
SocketUnitySocketSend=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
IPAddressHostIpAddress=IPAddress.Parse(".0.0.1");
UnitySocketSend.Bind(newIPEndPoint(HostIpAddress,));
while(true)
{
SendedString=Console.ReadLine();
MemoryStreamStreamSendString=newMemoryStream();
RijndaelRijndaelAlg=Rijndael.Create();
CryptoStreamCStream=newCryptoStream(StreamSendString,RijndaelAlg.CreateEncryptor(RijndaelAlg.Key,RijndaelAlg.IV),CryptoStreamMode.Write);
UnitySocketSend.SendTo(SendedString,newIPEndPoint(HostIpAddress,));
}
}
}
}
此处RijndaelAlg.Key和RijndaelAlg.IV既是密钥,由于Rijndael是对称算法,解密也是用它们做密钥。
四、将要发送的消息写入加密流:
namespaceConsoleApplication02
{
classProgram
{
staticvoidMain(string[]args)
{
stringSendedString="HelloWorld!";
SocketUnitySocketSend=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
IPAddressHostIpAddress=IPAddress.Parse(".0.0.1");
UnitySocketSend.Bind(newIPEndPoint(HostIpAddress,));
while(true)
{
SendedString=Console.ReadLine();
MemoryStreamStreamSendString=newMemoryStream();
RijndaelRijndaelAlg=Rijndael.Create();
CryptoStreamCStream=newCryptoStream(StreamSendString,RijndaelAlg.CreateEncryptor(RijndaelAlg.Key,RijndaelAlg.IV),CryptoStreamMode.Write);
CStream.Write(Encoding.UTF8.GetBytes(SendedString),0,Encoding.UTF8.GetBytes(SendedString).Length);
CStream.Flush();
CStream.Close();
UnitySocketSend.SendTo(SendedString,newIPEndPoint(HostIpAddress,));
}
}
}
}
五、使用流的ToArray()函数提取流的信息,然后发送出去:
namespaceConsoleApplication02
{
classProgram
{
staticvoidMain(string[]args)
{
stringSendedString="HelloWorld!";
SocketUnitySocketSend=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
IPAddressHostIpAddress=IPAddress.Parse(".0.0.1");
UnitySocketSend.Bind(newIPEndPoint(HostIpAddress,));
while(true)
{
SendedString=Console.ReadLine();
MemoryStreamStreamSendString=newMemoryStream();
RijndaelRijndaelAlg=Rijndael.Create();
CryptoStreamCStream=newCryptoStream(StreamSendString,RijndaelAlg.CreateEncryptor(RijndaelAlg.Key,RijndaelAlg.IV),CryptoStreamMode.Write);
CStream.Write(Encoding.UTF8.GetBytes(SendedString),0,Encoding.UTF8.GetBytes(SendedString).Length);
CStream.Flush();
CStream.Close();
Byte[]SendedString01=StreamSendString.ToArray();
StreamSendString.Close();
UnitySocketSend.SendTo(SendedString01,newIPEndPoint(HostIpAddress,));
}
}
}
}
六、按Ctrl+F5测试,能够很好的加密。加密了就要能解密,Rijndael算法是对称加密算法,加密和解密使用同一个密钥,Rijndael算法的Key属性返回Byte类型数据。