How to detect if DownloadString Failed? - vb.net

I'm trying to put my External IP in a Label, so I'm downloading the result based on a site, but the moment I change my IP via VPN, the application crashes, I believe it's because it does not check if it's getting the string down, that he tried.
On form load...
If Label1.Text = LastIp Then
Try
Dim wc As New WebClient
Label1.Text = wc.DownloadString("http://icanhazip.com/")
If you can not then
Label.Text = "Failed to get IP"
End if
End If
Form...

You could set up a callback and specify the path to the file:
Dim wc As New WebClient
AddHandler wc.DownloadStringCompleted, AddressOf DownloadStringComplete
wc.DownloadStringAsync(New Uri("http://icanhazip.com/myfile.txt", UriKind.Absolute))
Private Sub DownloadStringComplete(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
If Not IsNothing(e.Error) Then
Label1.Text = e.Error.Message
ElseIf e.Cancelled Then
Label1.Text = "canceled"
Else
Label1.Text = e.Result
End If
End Sub

Related

Threading doesn't complete the task before ending the thread loop

So I did something similar a while ago, but this is essentially a username checker for a (specific) website, they can load in usernames via text file and it will put it into a list box, now I have the start button and it's meant to check each username. Before, however, it froze the program when they checked, but it worked. I tried making it "threaded" so it didn't freeze.
The problem now is that it doesn't check them all, and finishes instantly.
CODE:
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
Button6.Enabled = False
Dim goodUsers As New SaveFileDialog()
goodUsers.Filter = "TXT file (*.txt)|*.txt"
Dim flag As Boolean
Dim Incomplete As Integer = 0
Dim Taken As Integer = 0
Dim sb As New StringBuilder
If goodUsers.ShowDialog() = DialogResult.OK Then
Dim checkerMT As New Thread(
Sub()
For Each i As String In UsernameList.Items
WebRequest.Create("http://yatobooter.cf/other/checkusr.php?username=" + i.ToString)
Dim cResult As String = New System.Net.WebClient().DownloadString("http://yatobooter.cf/other/checkusr.php?username=" + i.ToString).ToString
If cResult = "taken" Then
flag = False
ElseIf cResult = "nottaken" Then
flag = True
End If
If flag = True Then
sb.Append(i & vbNewLine)
Else
Incomplete = Incomplete + 1
Taken = UsernameList.Items.Count - Incomplete
End If
Next
End Sub
)
checkerMT.Start()
Try
File.WriteAllText(goodUsers.FileName, sb.ToString)
Catch ex As Exception
Exit Sub
End Try
End If
MessageBox.Show("Checking available usernames, complete!", "NameSniper Pro")
Button6.Enabled = True
End Sub
You cannot access UI elements (UsernameList.Items) from a thread other than the UI. Instead add a background worker to your form to handle the basic threading stuff (progress reporting, finish reporting, exception handling). Pass into this an object that contains the settings your job needs to do its work without interacting with the ui.
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
Button6.Enabled = False
Dim goodUsers As New SaveFileDialog()
goodUsers.Filter = "TXT file (*.txt)|*.txt"
If goodUsers.ShowDialog() = DialogResult.OK Then
'Note: You'll need to add the filenames
BackgroundWorker1.RunWorkerAsync(New State() With {.Names = {}, .FileName = goodUsers.FileName})
End If
End Sub
Class State
Public Names As List(Of String)
Public StringBuilder As New System.Text.StringBuilder
Public Incomplete As Integer
Public Taken As Integer
Public FileName As String
End Class
Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim state = CType(e.Argument, State)
For Each i As String In state.Names
Using cli = New System.Net.WebClient()
Dim cResult = cli.DownloadString("http://yatobooter.cf/other/checkusr.php?username=" + i.ToString).ToString
If cResult = "nottaken" Then
state.StringBuilder.Append(i & vbNewLine)
Else
state.Incomplete = state.Incomplete + 1
state.Taken = state.Names.Count - state.Incomplete
End If
End Using
Next
IO.File.WriteAllText(state.FileName, state.StringBuilder.ToString)
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
If e.Error IsNot Nothing Then
MessageBox.Show(e.Error.ToString(), "Error")
Else
MessageBox.Show("Checking available usernames, complete!", "NameSniper Pro")
End If
Button6.Enabled = True
End Sub
The SaveFileDialog can be used as "Using directive"
Why do you create a webrequest on the one hand, and on the other hand use a webclient? That does not make sense at all.
Instead of your strange if condition, write:
flag = (cResult.Equals("nottaken"))
All code you want to run after the actions you are currently running in your thread have to be in your thread as well, because it is async.
You have to invoke if you use user controls within a thread
and so on..
Please turn Option Strict On and Option Infer Off
There are lots of other things you could do better.
Please remove the webrequest and webclient combination yourself, that does not make sense at all.
Take a look at this, I cleared it a little bit:
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
Dim Incomplete As Integer = 0
Dim Taken As Integer = 0
Dim sb As New StringBuilder
Using goodUsers As SaveFileDialog = new SaveFileDialog()
goodUsers.Filter = "TXT file (*.txt)|*.txt"
If not goodUsers.ShowDialog() = DialogResult.OK Then Exit Sub
Dim checkerMT As New Thread(
Sub()
Me.invoke(sub()
Button6.Enabled = False
For Each i As String In UsernameList.Items
WebRequest.Create("http://yatobooter.cf/other/checkusr.php?username=" + i.ToString)
Dim cResult As String = New System.Net.WebClient().DownloadString("http://yatobooter.cf/other/checkusr.php?username=" + i.ToString).ToString
If (cResult.toLower().Equals("nottaken")) Then
sb.Append(String.Concat(i , Environment.NewLine)
Else
Incomplete += 1
Taken = UsernameList.Items.Count - Incomplete
End If
Next
File.WriteAllText(goodUsers.FileName, sb.ToString)
Button6.Enabled = True
MessageBox.Show("Checking available usernames, complete!", "NameSniper Pro")
End Sub)
End Sub
)
checkerMT.IsBackground = True;
checkerMT.Start()
End Sub

VB.Net BackgroundWorker and AsyncCancel Not Working Correctly

Hello again StackOverflow Community!
I am having some issues with a BackgroundWorker and AsyncCancel. The BackgroundWorker simply sends a email but I would like to be able to report when the task or email has been sent and as well be able to cancel the task or email from being sent.
The problem is after hitting cancel, it continues and then reports a error, not canceled.
Any help is greatly appreciated!
Thank you!
Here is my complete code minus comments and imports:
Private Sub Sendmail_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
StatusLabel.Text &= "Idle"
End Sub
Private Sub SendmailBackgroundWorker_DoWork(sender As Object, e As DoWorkEventArgs) Handles SendmailBackgroundWorker.DoWork
Try
Dim Smtp As New SmtpClient()
Dim Email As New MailMessage()
Smtp.Port = 25
Smtp.Host = "mail.server.com"
Smtp.EnableSsl = False
Smtp.UseDefaultCredentials = False
Smtp.Credentials = New Net.NetworkCredential("user#server.com", "password")
Email = New MailMessage()
Email.From = New MailAddress(FromTextBox.Text)
Email.To.Add(ToTextBox.Text)
Email.Subject = SubjectTextBox.Text
Email.IsBodyHtml = False
Email.Body = BodyTextBox.Text
Smtp.Send(Email)
Catch ex As Exception
MsgBox("Sendmail Error!" & vbNewLine & vbNewLine & ex.ToString)
End Try
If SendmailBackgroundWorker.CancellationPending Then
StatusLabel.Text = "Canceling"
e.Cancel = True
End If
End Sub
Private Sub SendmailBackgroundWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles SendmailBackgroundWorker.RunWorkerCompleted
StatusLabel.Text = "Status: "
If (e.Error IsNot Nothing) Then
StatusLabel.Text &= "Worker Error!" & vbNewLine & vbNewLine & e.Error.Message
ElseIf e.Cancelled Then
StatusLabel.Text &= "Canceled!"
Else
StatusLabel.Text &= "Sent!"
End If
SendButton.Enabled = True
CancelButton.Enabled = False
End Sub
Private Sub SendButton_Click(sender As Object, e As EventArgs) Handles SendButton.Click
StatusLabel.Text = "Status: "
SendButton.Enabled = False
CancelButton.Enabled = True
SendmailBackgroundWorker.WorkerSupportsCancellation = True
SendmailBackgroundWorker.WorkerReportsProgress = True
StatusLabel.Text &= "Sending..."
SendmailBackgroundWorker.RunWorkerAsync()
End Sub
Private Sub CancelButton_Click(sender As Object, e As EventArgs) Handles CancelButton.Click
CancelButton.Enabled = False
SendmailBackgroundWorker.CancelAsync()
End Sub
That is working exactly as it should. The problem is that you haven't read up properly on how it works. Calling CancelAsync (NOT AsyncCancel) on a BackgroundWorker does NOT cancel anything. All it does is set a flag on the BackgroundWorker object. It's up to you to test that flag in your DoWork event handler and, if it's set, it's then for you to stop the work. In your current code, you're not testing that flag until after the email has been sent so of course the email gets sent whether you try to cancel or not.
You are overestimating what cancelling a BackgroundWorker can accomplish. The BackgroundWorker itself doesn't know what you're doing in the DoWork event handler so it's not going to simply abort it. It gives you the chance to terminate the task at an appropriate point in the code. If there is no appropriate point then you can't cancel anything.
In your case, once you call Send on your SmtpClient, you can't do anything until that synchronous method returns, so you can't cancel it. What you should be doing is not using a BackgroundWorker at all but rather the asynchronous functionality built into the SmtpClient class. It has a SendAsync method and a SendAsyncCancel method, so you can let it handle the multithreading for you.

Tcp Client/Server - Client messages issue

I have client and server application.
I have the client disconnect from the server with client.close via a disconnect button.
I send a message, shows on server. ok works great.
I disconnect and then reconnect. I send a message. It shows the message two times.
I disconnect another time then reconnect. I send a message. It then shows the message three times.
It is incrementing the message and sending it multiple times after the disconnect and then reconnect.
Help? Been trying to figure this out for a while
[SERVER]
Public Class Server
Dim Listener As TcpListener
Dim Client As TcpClient
Dim ListenerThread As System.Threading.Thread
Dim ClientID As String
Dim ClientIP As String
Dim ClientIPandID As String
Dim ClientIPandPort As String
Dim TotalItemCount As String
Dim clientcount As Integer = 0
Private Sub Server_Load(sender As Object, e As EventArgs) Handles Me.Load
CheckForIllegalCrossThreadCalls = False
End Sub
Private Sub ButtonStart_Click(sender As System.Object, e As System.EventArgs) Handles ButtonStart.Click
If TextBoxPort.Text = "" Then
MsgBox("Please Enter Port To Run On.")
Else
ListenerThread = New System.Threading.Thread(AddressOf Listening)
ListenerThread.IsBackground = True
ListenerThread.Start(TextBoxPort.Text)
ButtonStart.Enabled = False
ButtonStop.Enabled = True
ListBox1.Items.Add("[SERVER] Running on Port " + TextBoxPort.Text)
ListBox1.Items.Add("[SERVER] Waiting For A Connection...")
End If
End Sub
Private Sub Listening(ByVal Port As Integer)
Try
Listener = New TcpListener(IPAddress.Any, Port)
Listener.Start()
Do
Client = Listener.AcceptTcpClient 'Accepts Client Trying To Connect
If Client.Connected Then
MsgBox("Client Connected")
End If
clientcount += 1
GetClientInfo() 'Retrieves The Clients Info
AddHandler ReceivedMessage, AddressOf ReceivedMessage1
Loop Until False
Catch ex As Exception
End Try
End Sub
'Events
Public Event ReceivedMessage(ByVal Command As String)
Private Sub GenerateClientSessionNumber()
Dim r As New Random
Dim x As String = String.Empty
For i = 0 To 7
x &= Chr(r.Next(65, 89))
Next
ClientID = x
End Sub
Private Sub GetClientInfo()
GenerateClientSessionNumber()
ClientIPandID = Client.Client.RemoteEndPoint.ToString().Remove(Client.Client.RemoteEndPoint.ToString().LastIndexOf(":")) & " - " & ClientID
ClientIP = Client.Client.RemoteEndPoint.ToString().Remove(Client.Client.RemoteEndPoint.ToString().LastIndexOf(":"))
ClientIPandPort = Client.Client.RemoteEndPoint.ToString()
MsgBox(ClientIPandPort)
ListBox2.Items.Add(ClientIPandID)
Client.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf Reading, Nothing)
End Sub
Private Sub ButtonStop_Click(sender As System.Object, e As System.EventArgs) Handles ButtonStop.Click
Listener.Stop()
Client.Close()
ButtonStop.Enabled = False
ButtonStart.Enabled = True
ListBox1.Items.Add("[SERVER] Server Stopped")
End Sub
Private Sub Reading()
Try
Dim Reader As New StreamReader(Client.GetStream)
Dim Command As String = Reader.ReadLine
Client.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf Reading, Nothing)
RaiseEvent ReceivedMessage(command)
Catch ex As Exception
End Try
End Sub
Private Sub ReceivedMessage1(ByVal Command As String)
Dim Message() As String = Command.Split("|")
If Message(0) = "MESSAGE" Then
MsgBox("Message Received From Client " + ">" + Message(1))
End If
end sub
[CLIENT]
Public Class Client
Dim Client As New TcpClient
Sub Connect(ByVal ServerIP As String, ByVal Port As Integer)
'Try To Make Connection With Server
If Client.Connected = True Then
MsgBox("Already Connected")
MsgBox("Connected To " + Client.Client.RemoteEndPoint.ToString)
Else
MsgBox("Currently Not Connected. Trying To Connect...")
Try
Client.Connect(ServerIP, Port)
MsgBox("Connected")
Client.GetStream.BeginRead(New Byte() {0}, 0, 0, AddressOf Reading, Nothing)
Catch ex As Exception
MsgBox("Could Not Connect To Server. Check Server." + ex.Message.ToString)
End Try
End If
End Sub
Private Sub SendData(ByVal Message As String) 'Sends Data to Server
TextBox1.Text = Message
Try
If Client.Connected = True Then
Dim Writer As New StreamWriter(Client.GetStream)
Writer.WriteLine(Message)
Writer.Flush()
Else
MsgBox("Cannot Send Message. Connection To Server Is Not Active.")
End If
Catch ex As Exception
MsgBox("You Are Not Connected To The Server." + vbCrLf + ex.Message.ToString)
End Try
End Sub
Private Sub ButtonConnect_Click(sender As Object, e As EventArgs) Handles ButtonConnect.Click
Connect(TextBoxIPAddress.Text, TextBoxPort.Text)
End Sub
Private Sub ButtonSendMessage_Click(sender As Object, e As EventArgs) Handles ButtonSendMessage.Click
SendData("MESSAGE|" & TextBoxMessage.Text)
End Sub
Private Sub Client_Load(sender As Object, e As EventArgs) Handles MyBase.Load
CheckForIllegalCrossThreadCalls = False
End Sub
Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click
SendData("DISCONNECT|")
Client.Close()
Client = New TcpClient
End Sub
End Class
i am not sure about the problem but i can give you some hypothesizes, firstly you add handler on every client you connect on server side and that means multiple pointer to the same place, secondly when you connect to server and reconnect you actually don't tell the server that the two clients are the same so he make two channels between the client and the server, the first is the old one that didn't close and he still have handler on it, the server don't recognize that the first is disconnected because he is connected! even if its another object at client. so when client disconnects , disconnect him from server too, or at every loop test if clients are connected before accepting do this test .
Since I have a class Called "ConnectedClient". I was able to make a call to that specific client or all clients and Close/Destroy the connection.

VB.NET Progress bar on ftp upload

Hi I am trying to add a progress bar to a FTP image upload, though I looked at many examples over the internet and I've tried numerous things but just couldn't get anything to work with my following code. I want a progress bar to track the progress of the upload then show 100% once done.
My coding:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim s As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
Static r As New Random
Dim sb As New StringBuilder
For i As Integer = 1 To 8
Dim idx As Integer = r.Next(0, 35)
sb.Append(s.Substring(idx, 1))
Next
Clipboard.SetText("http://my-site.com/osdf/" + sb.ToString() + ".png")
Using ms As New System.IO.MemoryStream
sc.CaptureDeskTopRectangle(Me.boundsRect).Save(ms, System.Drawing.Imaging.ImageFormat.Png)
''Close()
Using wc As New System.Net.WebClient
AddHandler wc.UploadDataCompleted, AddressOf UploadCompleted
wc.UploadData("ftp://USERNAME:PASSWORD#My-site.com/pic/uploads/" + sb.ToString() + ".png", ms.ToArray())
End Using
MsgBox("File Uploaded", MsgBoxStyle.Information)
End Using
End Sub
How would I be able to do this using my code?
Thanks in advance, I will appreciate your support.
Change your code and use the WebClient event like:
Using wc As New System.Net.WebClient
AddHandler wc.UploadDataCompleted, AddressOf wc_UploadDataCompleted
AddHandler wc.UploadProgressChanged, AddressOf wc_UploadProgressChanged
wc.UploadData("ftp://USERNAME:PASSWORD#My-site.com/pic/uploads/" & sb.ToString() & ".png", ms.ToArray())
End Using
Also you need:
Private Sub wc_UploadDataCompleted(sender As Object, e As System.Net.UploadDataCompletedEventArgs)
MsgBox("File Uploaded", MsgBoxStyle.Information)
End Sub
Private Sub wc_UploadProgressChanged(sender As Object, e As System.Net.UploadProgressChangedEventArgs)
ProgressBar1.Value = e.ProgressPercentage
End Sub
you will need to use "UploadDataAsync" instead of "UploadData" to be able to see the increament in the progressbar or use a BackgroundWorker with UploadData method.

How to download from ftp without form lag vb.net

I just made a ftp chat in vb.net and it update message from a file from a ftp server
so i add a timer with interval 1000 with this code
Try
Dim client As New Net.WebClient
client.Credentials = New Net.NetworkCredential("fnet_1355****", "******")
RichTextBox1.Text = client.DownloadString("ftp://185.**.***.**/htdocs/chat­.txt")
Catch ex As Exception
End Try
so .. the file is downloaded and it update the text successful but there is a problem .. every time he download the form have a bit lag ... and i dont like that :D what i can do ?
RichTextBox1.Text = client.DownloadString("ftp://185.**.***.**/htdocs/chat­.txt")
Instead of this try async method.
client.DownloadStringAsync(new Uri("ftp://185.**.***.**/htdocs/chat­.txt"))
and then handle download string completed event.
Sample Code
client.DownloadStringAsync(new Uri("ftp://185.**.***.**/htdocs/chat­.txt"));
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
RichTextBox1.Text =e.Result;
}
You can also add progress indicator by handling progress change event.
The best way you can do it would be to use ThreadPool provided by the Framework to I/O bound operation on different thread.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf DownloadFromFtp))
End Sub
Private Sub DownloadFromFtp()
Try
Dim client As New Net.WebClient
client.Credentials = New Net.NetworkCredential("fnet_1355****", "******")
Dim response As String = client.DownloadString("ftp://185.**.***.**/htdocs/chat­.txt")
Me.Invoke(New MethodInvoker(Function() RichTextBox1.Text = response))
Catch ex As Exception
End Try
End Sub
This program was the exact one I design before i learned PHP.
Here try this:
Dim thrd As Threading.Thread
Dim tmr As New Timer
Dim tempstring As String
Private Sub thread_start()
thrd = New Threading.Thread(Sub() check_for_changes())
tmr.Interval = 50
AddHandler tmr.Tick, AddressOf Tick
tmr.Enabled = True
tmr.Start()
thrd.Start()
End Sub
Private Sub Tick(sender As Object, e As EventArgs)
If Not thrd.IsAlive Then
tmr.Stop() : tmr.Enabled = False
RichTextBox1.Text = tempstring
End If
End Sub
Private Sub check_for_changes()
Try
Dim client As New Net.WebClient
client.Credentials = New Net.NetworkCredential("fnet_1355****", "******")
tempstring = client.DownloadString("ftp://185.**.***.**/htdocs/chat­.txt")
Catch ex As Exception
End Try
End Sub
Hope It Helps.