public void SetRemoteFolder(String thePath) { String errMsg = ""; client.SendText("<command=setpath>" + thePath, ref errMsg); }
public bool Send(String _filePath, String _baseFolder, String _targetFolder, String _streamName, int mbPerSec = 1000, bool block = false) { this.filePath = _filePath; this.baseFolder = _baseFolder; this.targetFolder = _targetFolder; this.streamName = _streamName; this.connectionLost = false; bool retVal = true; bool transferOk = true; bool writeFailed = false; FileInfo thisFileinfo; int lastRead = 0; bytesWritten = 0; totalBytesWritten = 0; complete = false; errMsg = ""; if (File.Exists(filePath)) { thisFileinfo = new FileInfo(filePath); lastWritten = thisFileinfo.LastWriteTime; length = thisFileinfo.Length; } else { errMsg = "Transfer failed: The Source file does not exist."; retVal = false; running = false; return(false); } createNewFailed = false; creatNewSucceeded = false; if (running) { errMsg = "Transfer failed: A file is already being sent by this Transfer object."; return(false); } running = true; new Thread(() => { // Convert this to long form: mbPerSec = (mbPerSec * 1000000); // Convert it to bytes. mbPerSec = (mbPerSec / 8); // We don't want to send more then mbPerSec bytes a second, so // If buffersize if larger then it may happen. Let's make sure it // doesn't. if (bufferSize > mbPerSec) { bufferSize = mbPerSec; } try { // Create the reader filestream: fs = new FileStream(filePath, FileMode.Open); } catch (Exception ex) { errMsg = "file aborted: Could not access the source file: " + Path.GetFileName(filePath) + ". The error returned is: " + ex.Message; retVal = false; running = false; return; } // Define the cleanup function (it will be called from several different places). Action <String> cleanUp = (String msg) => { if (closeDatastream) { CloseDatastream(streamName); } try { // We're finished with the source file, so close it. fs.Close(); } catch (Exception) { } callback(msg); running = false; }; // Make sure we haven't been stopped before we even begin: if (!client.Running()) { running = false; cleanUp("file aborted - FileTransfer not running! (" + Path.GetFileName(filePath) + ")"); return; } // Define our DataStream name: if (streamName.Equals("")) { streamName = filePath.Replace(@"\", "-"); closeDatastream = true; } Func <String, bool, bool> GetDataStream = (String thisStreamName, bool killExisting) => { // Are we creating a new datastream for every transfer (slower), or reusing one over and over (faster) if (closeDatastream || killExisting) { CloseDatastream(thisStreamName); } // Get the tcp DataStream if (!client.GetDataStream(thisStreamName, ref thisDataStream, ref errMsg)) { if (!client.CreateDataStream(thisStreamName, ref errMsg)) { errMsg = "file aborted (connection lost)! ( Could not create DataStream '" + streamName + "' )"; CloseDatastream(thisStreamName); retVal = false; running = false; return(false);; } if (!client.GetDataStream(thisStreamName, ref thisDataStream, ref errMsg)) { errMsg = "file aborted (connection lost)! ( Could not get DataStream '" + streamName + "' )"; CloseDatastream(thisStreamName); retVal = false; running = false; return(false); } } return(true); }; if (!GetDataStream(streamName, false)) { retVal = false; cleanUp(errMsg); return; } // Re-define the DataStream's callback here so we can get control messages from it: thisDataStream.callback = delegate(string msg, byte[] dataStreamBuffer, int numBytesContained, string sessionId) { if (dataStreamBuffer != null) { String thisMsg = TcpComm.Utilities.BytesToString(dataStreamBuffer, numBytesContained); if (thisMsg == "complete:ok") { complete = true; } if (thisMsg == "complete:failed") { transferOk = false; complete = true; } if (thisMsg == "new:ok") { creatNewSucceeded = true; } if (thisMsg.StartsWith("new:failed:")) { errMsg = thisMsg.Replace("new:failed:", "Transfer Failed: "); createNewFailed = true; } if (thisMsg.StartsWith("writefailed:")) { writeFailed = true; } if (thisMsg.StartsWith("written:")) { thisMsg = thisMsg.Replace("written:", ""); try { bytesWritten = int.Parse(thisMsg); } catch (Exception) { retVal = false; cleanUp("Transfer Failed: Could not read (parse) the number of bytes written by the server. Communication error."); return; } } } }; // Define a control message of our own here: String newCommand = "<command=new><path>" + filePath.Replace(baseFolder, "") + @"</path>"; if (File.Exists(filePath)) { newCommand += "<length>" + length.ToString() + @"</length><date>" + lastWritten.ToString() + @"</date><targetfolder>" + targetFolder + "</targetfolder>"; } else { retVal = false; cleanUp("Transfer failed: The source file does not exist."); return; } // Send our "new file transfer" control message to the file transfer server here: if (!client.SendText(newCommand, streamName, ref errMsg)) { errMsg = "file aborted (connection lost)! Could not communicate with server: " + errMsg; try { fs.Close(); } catch (Exception) { } retVal = false; cleanUp(errMsg); return; } // Wait for the server's response for up to 3 second: new Tools.WaitTimeout(3000, () => { return(createNewFailed || creatNewSucceeded); }).Wait(); // Did the server have a problem with our proposed transfer (or did it fail to respond within 3 seconds)? if (createNewFailed) { try { fs.Close(); } catch (Exception) { } retVal = false; cleanUp(errMsg); return; } // The transfer has been accepted - on to the good stuff: try { // Get the first chunk of file bytes that will be sent: read = fs.Read(buffer, 0, bufferSize); lastRead = read; } catch (Exception ex) { errMsg = "Transfer failed: Can not read from source file: " + ex.Message; retVal = false; cleanUp(errMsg); return; } if (mbPerSec > 0 && bufferSize > (mbPerSec / 4)) { bufferSize = mbPerSec / 4; } DateTime timeout = DateTime.Now.AddSeconds(1); int sentThisSec = 0; // Begin sending file bytes: while (read > 0 && running && client.Running()) { // Respect the throttle value here: if (mbPerSec > 0) { if (sentThisSec >= mbPerSec && DateTime.Now < timeout) { while (DateTime.Now < timeout) { Thread.Sleep(1); } } if (DateTime.Now >= timeout) { timeout = DateTime.Now.AddSeconds(1); sentThisSec = 0; } } // Actually send the bytes we've read here: bytesWritten = 0; if (!client.SendArray(buffer, read, streamName, ref errMsg)) { errMsg = "file aborted (connection lost)! Can not communicate with file transfer server: " + errMsg; retVal = false; cleanUp(errMsg); return; } sentThisSec += read; totalBytesWritten += read; try { // Get some more bytes: read = fs.Read(buffer, 0, bufferSize); } catch (Exception ex) { errMsg = "file aborted (connection lost)! Can not read from source file: " + ex.Message; retVal = false; cleanUp(errMsg); return; } // Wait for the server to acknolage the last chunk of bytes read and sent: packetTimeout = DateTime.Now.AddSeconds(15); while (bytesWritten != lastRead && running && client.Running()) { Thread.Sleep(1); if (DateTime.Now > packetTimeout) { // We've lost connection for some reason. Bail: connectionLost = true; break; } if (writeFailed) { connectionLost = true; break; } } if (connectionLost) { break; } lastRead = read; } try { // We're finished with the source file, so close it. fs.Close(); } catch (Exception) { } if (writeFailed) { errMsg = "file aborted (connection lost)! A transfer operation with this ID could not be found in the server. "; retVal = false; cleanUp(errMsg); return; } if (totalBytesWritten < length && !client.Running()) { errMsg = "file aborted (connection lost)! Can not communicate with file transfer server: " + errMsg; retVal = false; cleanUp(errMsg); return; } // Finishing up: has the client disconnected? if (!client.Running()) { running = false; } // Did we loose connection? if (connectionLost) { // Attempt to send this no matter what: CloseDatastream(streamName); errMsg = "file aborted: connection lost during transfer! (" + Path.GetFileName(filePath) + ")"; retVal = false; cleanUp(errMsg); return; } // Are we being asked to shut down? if (!running) { if (!client.SendArray(TcpComm.Utilities.StringToBytes("<command=abort>"), streamName, ref errMsg)) { //running = false; } CloseDatastream(streamName); errMsg = "file aborted! (" + Path.GetFileName(filePath) + ")"; retVal = false; cleanUp(errMsg); return; } if (!client.SendArray(TcpComm.Utilities.StringToBytes("<command=complete>" + length.ToString()), streamName, ref errMsg)) { errMsg = "file aborted! (Could not send file complete message)"; retVal = false; cleanUp(errMsg); return; } // Wait for the server to acknolage that we're finished sending bytes for this file: new WaitTimeout(14000, () => { return(complete || !running); }).Wait(); if (!complete) { errMsg = "file aborted (connection lost)! (" + Path.GetFileName(filePath) + ")"; CloseDatastream(streamName); retVal = false; cleanUp(errMsg); return; } if (!transferOk) { errMsg = "file aborted (target corrupt)! (" + Path.GetFileName(filePath) + ")"; CloseDatastream(streamName); retVal = false; cleanUp(errMsg); return; } // Clean up and exit. retVal = true; cleanUp("file Complete: " + Path.GetFileName(filePath)); }).Start(); if (block) { while (running) { Thread.Sleep(1); } } return(retVal); }
private void Update(byte[] bytes, byte dataChannel) { try { bool dontReport = false; if (dataChannel < 251) { // Try to execute command and send reply to caller if (bytes.Length < 65535) { TryExecuteCommand(TcpComm.Utilities.BytesToString(bytes)); } } else if (dataChannel == 255) { String message = TcpComm.Utilities.BytesToString(bytes); String tmp = string.Empty; // Receiving file in progress if (message.Length > 15) { tmp = message.Substring(0, 15); if (tmp == "Receiving file:") { this.EventLog.WriteEntry(message + " " + _client.GetIncomingFileName()); dontReport = true; } } // Sending file in progress if (message.Length > 13) { tmp = message.Substring(0, 13); if (tmp == "Sending file:") { this.EventLog.WriteEntry(message + " " + _client.GetOutgoingFileName()); dontReport = true; } } // Completed file receiving if (message == "->Done") { string errMsg = ""; _client.SendText(_client.GetMachineID() + ":FILE_RECEIVED", errMsg: ref errMsg); this.EventLog.WriteEntry(message); dontReport = true; } //Completed file sending if (message == "<-Done") { this.EventLog.WriteEntry(message); dontReport = true; } // Aborted file receiving if (message == "->Aborted") { string errMsg = ""; _client.SendText(_client.GetMachineID() + ":FILE_RECEIVING_ABORTED", errMsg: ref errMsg); this.EventLog.WriteEntry(message); dontReport = true; } // Aborted file sending if (message == "<-Aborted") { this.EventLog.WriteEntry(message); dontReport = true; } // UBS = User Bytes Sent on channel :??? if (message.Length > 4) { tmp = message.Substring(0, 4); if (tmp == "UBS:") { this.EventLog.WriteEntry(message); dontReport = true; } } // An error occured if (message.Length > 4) { tmp = message.Substring(0, 5); if (tmp == "ERR: ") { this.EventLog.WriteEntry("Wystąpił błąd: " + message); dontReport = true; } } // Server has disconnected (attempt to reconnect) if (message.Equals("Disconnected.")) { _isConnected = false; dontReport = true; } // Unknown message if (!dontReport) { this.EventLog.WriteEntry("Nieznany typ wiadomości: " + message); } } } catch { // ignored } }