Решил плотно освоить тему работы с сетью в .NET. Остановился на передаче файлов через сеть. Алгоритм такой: считываю файл в байтовый массив, высчитываю его длину и MD5 хеш. Делаю коннект на сервер, передаю длину, хеш, затем блоками по 4096 байт передаю файл. В общем - передача через раз заканчивается ошибкой. На той стороне хеш после сборки не совпадает. Код клиента (только функция передачи): | Код | private void btnSend_Click(object sender, EventArgs e) { byte[] fileContents = File.ReadAllBytes(txtFileName.Text); byte[] hash = new MD5CryptoServiceProvider().ComputeHash(fileContents);
txtLog.AppendText("Computed MD5 hash\n"); txtLog.AppendText(string.Format("Hash is: {0}\n", MD5Lib.HashToString(hash)));
try { using (TcpClient client = new TcpClient()) { client.SendBufferSize = client.ReceiveBufferSize = 4096; client.Connect(txtIP.Text, 8080); int fileSize = fileContents.Length; byte[] fileSizeData = BitConverter.GetBytes(fileSize); NetworkStream ns = client.GetStream(); ns.Write(fileSizeData, 0, fileSizeData.Length); ns.Write(hash, 0, hash.Length); ns.Flush(); int blockSize = client.SendBufferSize; int blocksCount = (int)Math.Ceiling((float)fileSize / (float)blockSize); int sentDataBytesCount = 0; for (int i = 0; i < blocksCount; i++) { int packetSize = Math.Min(fileSize - sentDataBytesCount, blockSize); ns.Write(fileContents, sentDataBytesCount, packetSize); sentDataBytesCount += packetSize; ns.Flush(); } ns.Close(); client.Close(); } } catch (Exception ex) { txtLog.AppendText(ex.Message.ToString() + "\n"); } }
|
Код сервера: | Код | using System; using System.Net.Sockets; using System.IO; using System.Security.Cryptography; using System.Net; using MD5Libs;
namespace Receiver { class Program { static void Main(string[] args) { try { Console.WriteLine("Waiting for a file..."); IPAddress local_addr = IPAddress.Parse("10.0.0.181"); TcpListener listener = new TcpListener(local_addr, 8080); listener.Start();
while (true) while (listener.Pending()) listener.BeginAcceptTcpClient(ClientAccept, listener); } catch (Exception ex) { Console.WriteLine("Ooops! {0}", ex.Message); } Console.ReadLine(); }
private static void ClientAccept(IAsyncResult ar) { TcpListener listener = (TcpListener)ar.AsyncState;
TcpClient client = listener.EndAcceptTcpClient(ar);
client.SendBufferSize = client.ReceiveBufferSize = 4096;
NetworkStream ns = client.GetStream();
byte[] fileSizeData = new byte[4]; ns.Read(fileSizeData, 0, fileSizeData.Length);
int fileSize = BitConverter.ToInt32(fileSizeData, 0); Console.WriteLine("File size is: {0} bytes", fileSize);
byte[] hashData = new byte[16]; ns.Read(hashData, 0, hashData.Length);
Console.WriteLine("Hash data received"); Console.WriteLine("Hash: {0}", MD5Lib.HashToString(hashData));
byte[] data = new byte[4096]; byte[] fileContents = new byte[fileSize];
int blockSize = client.ReceiveBufferSize; int blocksCount = (int)Math.Ceiling((float)fileSize / (float)blockSize); int rcvdDataBytesCount = 0;
for (int i = 0; i < blocksCount; i++) { int packetSize = Math.Min(fileSize - rcvdDataBytesCount, blockSize); ns.Read(fileContents, rcvdDataBytesCount, packetSize); rcvdDataBytesCount += packetSize; Console.WriteLine("Received block #{0}", i + 1); }
Console.WriteLine("All blocks received");
byte[] checkHashData = new MD5CryptoServiceProvider().ComputeHash(fileContents); Console.WriteLine("Check hash: {0}", MD5Lib.HashToString(checkHashData));
ns.Close(); client.Close();
if (HashesEqual(hashData, checkHashData)) { Console.WriteLine("Hashes are equal"); string fileName = @"c:\data.bin"; File.WriteAllBytes(fileName, fileContents); } else { Console.WriteLine("Wrong hash data"); } }
private static bool HashesEqual(byte[] hash1, byte[] hash2) { for (int i = 0; i < 16; i++) if (hash1[i] != hash2[i]) return false; return true; } } }
|
Ошибка возникает при передаче на стороне клиента: соединение якобы закрывается сервером. Укажите, какие ошибки я допустил в этом коде, как его можно улучшить, поделитесь своим опытом. Заранее спасибо за внимание.
--------------------
 Тонет Ктулху, все медведы горят в огне. Я Креведко, очень страшно сегодня мне.
|