public ClientSendResult SendFile(FileMetaData data) { ClientSendResult args = new ClientSendResult(); args.FileData = data; TcpClient client = new TcpClient(_connection.Address, _connection.Port); #if DEBUG == false //timeouts don't work well when you're debugging client.SendTimeout = 5000; #endif BufferedStream stream = new BufferedStream(client.GetStream()); BinaryReader reader = new BinaryReader(stream); BinaryWriter writer = new BinaryWriter(stream); try { //introduce ourselves if (Handshake(reader, writer) == true) { args.WasSuccessful = true; //tell server that we would like to send them a file IMessage message = new FileChangedMessage(data); writer.Write(message.ToBytes()); //see if server wants the file message = MessageFactory.FromStream(reader); //server says they want the whole load if (message.MessageId == MessageIdentifier.FileRequest) { message = new FileDataMessage(); writer.Write(message.ToBytes()); string basePath = _connection.LocalSyncPath; string localFilePath = Path.Join(basePath, data.Path); if (File.Exists(localFilePath)) { FileInfo toSend = new FileInfo(localFilePath); using (var fileReader = new BinaryReader(File.OpenRead(localFilePath))) { byte[] buffer; writer.Write(IPAddress.HostToNetworkOrder(toSend.Length)); while ((buffer = fileReader.ReadBytes(BUFFER_SIZE)).Length > 0) { writer.Write(buffer); } writer.Flush(); } } } } } catch (EndOfStreamException ex) { //end of stream exception doesn't necessairly mean that the transfer was not successful so separate out //from generic exception } catch (Exception ex) { args.WasSuccessful = false; _logger.Log("Error: {0}", ex.Message); } finally { client.Close(); } return(args); }
protected IMessage ProcessData(Connection connection, BinaryReader reader) { IMessage result = new NullMessage(); IMessage currentMessage = MessageFactory.FromStream(reader); switch (currentMessage.MessageId) { case MessageIdentifier.FileChanged: { if (ClientHasBeenValidated == true) { FileChangedMessage message = currentMessage as FileChangedMessage; string filePath = Path.Join(connection.LocalSyncPath, message.FileData.Path); FileInfo localFile = new FileInfo(filePath); //we only need the file data when a file on the client was changed and that file is newer than our local copy if (message.FileData.OperationType == WatcherChangeTypes.Changed || message.FileData.OperationType == WatcherChangeTypes.Created) { if (localFile.Exists == false || localFile.LastWriteTimeUtc < message.FileData.LastWriteTimeUtc) { FileMetaData = message.FileData; result = new FileRequestMessage(message.FileData); } else { result = new NullMessage(); } } else { if (message.FileData.OperationType == WatcherChangeTypes.Renamed) { string oldFilePath = Path.Join(connection.LocalSyncPath, message.FileData.OldPath); if (File.Exists(oldFilePath)) { File.Move(oldFilePath, filePath); } } if (message.FileData.OperationType == WatcherChangeTypes.Deleted) { if (File.Exists(filePath)) { File.Delete(filePath); } } result = new NullMessage(); } } break; } case MessageIdentifier.FileData: { if (ClientHasBeenValidated == true && FileMetaData != null) { FileDataMessage message = currentMessage as FileDataMessage; message.FilePath = Path.Join(connection.LocalSyncPath, FileMetaData.Path); ReceiveBegin(this, new ServerEventArgs() { FileData = FileMetaData, FullLocalPath = message.FilePath }); try { message.FromBinaryStream(reader); //change last write to match client file File.SetLastWriteTimeUtc(message.FilePath, FileMetaData.LastWriteTimeUtc); File.SetLastAccessTimeUtc(message.FilePath, FileMetaData.LastAccessTimeUtc); File.SetCreationTimeUtc(message.FilePath, FileMetaData.CreateTimeUtc); ReceiveEnd(this, new ServerEventArgs() { FileData = FileMetaData, FullLocalPath = message.FilePath, Success = true }); } catch (Exception ex) { Logger.Log(LogPriority.High, "Server #{0} error writing file: {1}", ServerId, message.FilePath); ReceiveEnd(this, new ServerEventArgs() { FileData = FileMetaData, FullLocalPath = message.FilePath, Success = false }); } } break; } case MessageIdentifier.Verification: { VerificationMessage message = currentMessage as VerificationMessage; if (message != null) { if (message.Key == connection.LocalAccessKey) { result = new VerificationMessage(connection.RemoteAccessKey, NetworkResponse.Valid); //store validation result for later use ClientHasBeenValidated = true; } } break; } } return(result); }
private void FileChanged(FileChangedMessage obj) { FileDetail = fileDBAccess.GetFileByID(obj.Id); }