/// <summary> /// обработка сообщения GETUSERF /// </summary> /// <param name="iU"></param> /// <param name="data"></param> private void GetUserFiles(byte[] data) { byte[] buff; int buffSize = 5 * 2 + 1; string[] UsrFiles = Access.GetUserFiles(Login); for (int i = 0; i < UsrFiles.Length; i++) { buffSize += UsrFiles[i].Length * 2 + 1; //строки хранятся в паскаль-стиле, потому } // нужет ещё байт под размер для каждой строки buff = new byte[buffSize]; byte[] bLIST = Encoding.Unicode.GetBytes("LIST "); bLIST.CopyTo(buff, 0); buff[5 * 2] = (byte)UsrFiles.Length; int j = 5 * 2 + 1; for (int i = 0; i < UsrFiles.Length; i++) { ToPasString(UsrFiles[i], buff, j); j += UsrFiles[i].Length * 2 + 1; } CryWr.Write(ToAByte(buffSize), 0, 4); CryWr.Write(buff, 0, buffSize); iWr += 4 + buffSize; RoundWrStream(); Console.WriteLine("{0} получил список файлов ему принадлежащих", Login); ConLog.WriteLine("{0} получил список файлов ему принадлежащих", Login); }
/// <summary> /// функция записывает пустое сообщение в поток для того, что бы произошла запись из CryptoStream /// в NetworkStream. Иначе поток шифрования будет ждать пока прийдёт очередное сообщение и только /// тогда отправит данные по сети. И Flush() не помогает, нужно или дописывать ещё одно сообщение, /// либо удалять объект класса CryptoStream. /// </summary> private void RoundWrStream() { if (CryWr == null) { return; } byte[] B; int szB = (0x10 - (iWr & 0xF)) + 0x20; B = new byte[szB]; ToAByte(szB - 4).CopyTo(B, 0); B[4] = 0; try { CryWr.Write(B, 0, szB); } catch (Exception) { } iWr = 0; }
/// <summary> /// обработка сообщения GET /// </summary> /// <param name="iUser"></param> /// <param name="data"></param> private void SendFile(byte[] data) { string name = GetPasString(data, 4 * 2); string ThisLogin = Access.GetUser(name); int sizeDataFile; if (ThisLogin == Login) // проверкa хозяина файла { byte[] commFile = Encoding.Unicode.GetBytes("FILE "); FileStream inFS = File.OpenRead(name + ".zip"); sizeDataFile = (int)inFS.Length; int sizeMess = commFile.Length + 4;; int sizeFile = Access.GetFileSize(name); //первое сообщение с инфой о файле CryWr.Write(ToAByte(sizeMess), 0, 4); //размер вcего сообщения CryWr.Write(commFile, 0, commFile.Length); //команда CryWr.Write(ToAByte(sizeFile), 0, 4); //длина файла(до шифрования) //второе сообщение с файлом CryWr.Write(ToAByte(sizeDataFile), 0, 4); //размер вcего файла int rec = 0; while (rec < sizeDataFile) { int bufSize = Math.Min(1048576, sizeDataFile - rec); byte[] bufFile = new byte[bufSize]; inFS.Read(bufFile, 0, bufSize); CryWr.Write(bufFile, 0, bufSize); //данные файла rec += bufSize; } inFS.Dispose(); iWr += 4 + sizeMess + 4 + sizeDataFile; RoundWrStream(); } else { CryptoStream TStrWr = UsrRec.GetStreamWrByLogin(ThisLogin); if (TStrWr == null) { byte[] bCommand = Encoding.Unicode.GetBytes("ERROR"); CryWr.Write(ToAByte(bCommand.Length), 0, 4); //размер сообщения(без этих 4х байт) CryWr.Write(bCommand, 0, bCommand.Length); //команда iWr += 4 + bCommand.Length; RoundWrStream(); } else { SendResponse(TStrWr, "ACCESS ", Login); byte[] Key; if (!UsrRec.GetKey(ThisLogin, out Key)) { Console.WriteLine("{0}: неудачная попытка получить файл {1}", Login, name); ConLog.WriteLine("{0}: неудачная попытка получить файл {1}", Login, name); SendResponse(CryWr, "ERROR"); return; } byte[] commFilePswd = Encoding.Unicode.GetBytes("FILEPSWD "); byte[] sizeFile = ToAByte(Access.GetFileSize(name)); FileStream inFS = File.OpenRead(name + ".zip"); sizeDataFile = (int)inFS.Length; int sizeMess = commFilePswd.Length + 0x20 + 4; //первое сообщение с инфой о файле CryWr.Write(ToAByte(sizeMess), 0, 4); //размер сообщения(без этих 4х байт) CryWr.Write(commFilePswd, 0, commFilePswd.Length); //команда CryWr.Write(Key, 0, 0x20); //ключ CryWr.Write(sizeFile, 0, 4); //размер файла //второе сообщение с файлом CryWr.Write(ToAByte(sizeDataFile), 0, 4); //размер вcего файла int rec = 0; while (rec < sizeDataFile) //данные файла { int bufSize = Math.Min(1048576, sizeDataFile - rec); byte[] bufFile = new byte[bufSize]; inFS.Read(bufFile, 0, bufSize); CryWr.Write(bufFile, 0, bufSize); rec += bufSize; } inFS.Dispose(); iWr += 4 + sizeMess + 4 + sizeDataFile; RoundWrStream(); } } Console.WriteLine("{0}: получил файл {1}", Login, name); ConLog.WriteLine("{0}: получил файл {1}", Login, name); }