vb.net sending file over TCP - vb.net

I know similar questions like this have been asked on various forums, however none of the given solutions have worked for me, and was wondering if anyone had any other pointers they could give. I am basically trying to send a file (an image) over TCP between 2 computers on the same network. I have been trying to convert the image to a byte array, then to a string before sending the string. On the other side, I have received the string, converted to a byte array, and then convert back to an image. However, on the receiving side, the string is empty so I am getting an error when I then convert that to a byte array.
The code for the sending side is:
Private Sub startSending()
Dim ScreenShot As Image = sc.CaptureScreen
Dim path As String = My.Computer.FileSystem.SpecialDirectories.CurrentUserApplicationData + "\redsquirimgtest"
sc.CaptureScreenToFile(path, System.Drawing.Imaging.ImageFormat.Jpeg)
MsgBox("printscreen saved")
Dim abyt() As Byte = ConvertImageFiletoBytes(path)
MsgBox("image converted to byte array")
Dim str As String = byteArrToString(abyt)
MsgBox(str)
client.Connect("192.168.1.10", 55000)
Dim Writer As New StreamWriter(client.GetStream())
Writer.Write(str)
Writer.Flush()
MsgBox("sent")
Form2.PictureBox1.Image = ScreenShot
Form2.Show()
MsgBox("done")
End Sub
Public Function ConvertImageFiletoBytes(ByVal ImageFilePath As String) As Byte()
Dim _tempByte() As Byte = Nothing
If String.IsNullOrEmpty(ImageFilePath) = True Then
Throw New ArgumentNullException("Image File Name Cannot be Null or Empty", "ImageFilePath")
Return Nothing
End If
Try
Dim _fileInfo As New IO.FileInfo(ImageFilePath)
Dim _NumBytes As Long = _fileInfo.Length
Dim _FStream As New IO.FileStream(ImageFilePath, IO.FileMode.Open, IO.FileAccess.Read)
Dim _BinaryReader As New IO.BinaryReader(_FStream)
_tempByte = _BinaryReader.ReadBytes(Convert.ToInt32(_NumBytes))
_fileInfo = Nothing
_NumBytes = 0
_FStream.Close()
_FStream.Dispose()
_BinaryReader.Close()
Return _tempByte
Catch ex As Exception
Return Nothing
End Try
End Function
Public Function byteArrToString(ByVal arr() As Byte) As String
Return System.Text.Encoding.Unicode.GetString(arr)
End Function
And then the receiving side:
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
' Check the TcpListner Pending Property
If TcpListener.Pending = True Then
Dim Message As String = ""
ConnectClient = TcpListener.AcceptTcpClient()
MsgBox("accepting")
Dim Reader As New StreamReader(ConnectClient.GetStream())
While Reader.Peek > -1
Message = Message + Reader.Read().ToString
End While
MsgBox(Message)
Dim abyt() As Byte = StrToByteArray(Message)
MsgBox("string converted to byte array")
Dim img As Image = ConvertBytesToImageFile(abyt)
MsgBox("byte array converted to image")
PictureBox1.Image = img
MsgBox("picture loaded in form")
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
TcpListener.Start()
End Sub
Public Function ConvertBytesToImageFile(ByVal ImageData As Byte()) As Image
Dim myImage As Image
Dim ms As System.IO.Stream = New System.IO.MemoryStream(ImageData)
myImage = System.Drawing.Image.FromStream(ms)
Return myImage
End Function
Public Shared Function StrToByteArray(str As String) As Byte()
Return System.Text.Encoding.Unicode.GetBytes(str)
End Function
Thanks in advance for any help you can give!

Not sure if is the necessarily problem here, but I would suggest converting the bytes to string using System.Convert.ToBase64String(byte_array)
This will always give a safe string with no awkward characters which can be transmitted in various ways.

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
' Check the TcpListner Pending Property
If TcpListener.Pending = True Then
Dim Message As String = ""
ConnectClient = TcpListener.AcceptTcpClient()
MsgBox("accepting")
Dim Reader As New StreamReader(ConnectClient.GetStream())
While Reader.Peek > -1
Message = Message + Reader.Read().ToString
End While
MsgBox(Message)
Dim abyt() As Byte = StrToByteArray(Message)
MsgBox("string converted to byte array")
Dim img As Image = ConvertBytesToImageFile(abyt)
MsgBox("byte array converted to image")
PictureBox1.Image = img
MsgBox("picture loaded in form")
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
TcpListener.Start()
End Sub
Public Function ConvertBytesToImageFile(ByVal ImageData As Byte()) As Image
Dim myImage As Image
Dim ms As System.IO.Stream = New System.IO.MemoryStream(ImageData)
myImage = System.Drawing.Image.FromStream(ms)
Return myImage
End Function
Public Shared Function StrToByteArray(str As String) As Byte()
Return System.Text.Encoding.Unicode.GetBytes(str)
End Function

sc.CaptureScreen
sc.CaptureScreenToFile(path, System.Drawing.Imaging.ImageFormat.Jpeg)
sc. <-- ist nicht deklariert ERROR

Related

How to compare if a certain value all ready exist on my.settings vb.net

How to compare if a certain value all ready exist on my.settings vb.net
Hi i have start a new application and i have the application all much finish but i can not find the way to verify if a certain value its present on my.settings.md5_hashes .
So my application on the first form you can hash a string of each line on my text file and the insert is name and after the name its value.
My question is well i know how to retrieved the values and list the again on a listbox but how can i look if a certain string its exists?
this is my code
Imports System.IO
Imports System.Security.Cryptography
Imports System.Text
Public Class Form2
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If My.Settings.md5_hashes Is Nothing Then My.Settings.md5_hashes = New System.Collections.Specialized.StringCollection()
Dim openfile = New OpenFileDialog()
openfile.Filter = "Text (*.txt)|*.txt"
If (openfile.ShowDialog() = System.Windows.Forms.DialogResult.OK) Then
Dim myfile As String = openfile.FileName
Dim allLines As String() = File.ReadAllLines(myfile)
For Each line As String In allLines
'ListBox1.Items.Add(line)
Using hasher As MD5 = MD5.Create() ' create hash object
' Convert to byte array and get hash
Dim dbytes As Byte() =
hasher.ComputeHash(Encoding.UTF8.GetBytes(line))
' sb to create string from bytes
Dim sBuilder As New StringBuilder()
' convert byte data to hex string
For n As Integer = 0 To dbytes.Length - 1
sBuilder.Append(dbytes(n).ToString("X2"))
Next n
ListBox1.Items.Add(line + "<--->" + sBuilder.ToString)
My.Settings.md5_hashes.Add(line)
My.Settings.md5_hashes.Add(sBuilder.ToString)
My.Settings.Save()
End Using
Next
End If
For Each item In My.Settings.md5_hashes
ListBox1.Items.Add(item)
Next
If My.Settings.md5_hashes Is Nothing Then
Return
End If
MsgBox("All Imported Hashed And saved!")
ListBox1.Items.Clear()
End Sub
Shared Function GetHash(theInput As String) As String
Using hasher As MD5 = MD5.Create() ' create hash object
' Convert to byte array and get hash
Dim dbytes As Byte() =
hasher.ComputeHash(Encoding.UTF8.GetBytes(theInput))
' sb to create string from bytes
Dim sBuilder As New StringBuilder()
' convert byte data to hex string
For n As Integer = 0 To dbytes.Length - 1
sBuilder.Append(dbytes(n).ToString("X2"))
Next n
Return sBuilder.ToString()
End Using
End Function
Private Sub ListBox2_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListBox2.SelectedIndexChanged
End Sub
End Class
Try something like below. I threw in a "GetStoredHash()" function, but it's not being used; thought you'll need one of those eventually, though:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If My.Settings.md5_hashes Is Nothing Then
My.Settings.md5_hashes = New System.Collections.Specialized.StringCollection()
End If
Dim openfile As New OpenFileDialog()
openfile.Filter = "Text (*.txt)|*.txt"
If (openfile.ShowDialog() = System.Windows.Forms.DialogResult.OK) Then
Dim strHash As String
For Each line As String In File.ReadAllLines(openfile.FileName)
If Not IsValuePresent(line) Then ' prevent duplicates from being added to you collection
strHash = GetHash(line)
ListBox1.Items.Add(line + "<--->" + strHash)
My.Settings.md5_hashes.Add(line)
My.Settings.md5_hashes.Add(strHash)
My.Settings.Save()
End If
Next
End If
MessageBox.Show("All Imported Hashed And saved!")
ListBox1.Items.Clear()
End Sub
Public Function GetHash(ByVal theInput As String) As String
Static hasher As MD5 = MD5.Create() ' create and KEEP hash object so it can be re-used
Static sBuilder As New StringBuilder() ' sb to create string from bytes
' convert byte data to hex string
sBuilder.Clear()
For Each dbyte As Byte In hasher.ComputeHash(Encoding.UTF8.GetBytes(theInput))
sBuilder.Append(dbyte.ToString("X2"))
Next
Return sBuilder.ToString()
End Function
Private Function IsValuePresent(ByVal value As String) As Boolean
If My.Settings.md5_hashes Is Nothing Then
My.Settings.md5_hashes = New System.Collections.Specialized.StringCollection()
End If
Return My.Settings.md5_hashes.Contains(value)
End Function
Private Function GetStoredHash(ByVal value As String) As String
If My.Settings.md5_hashes Is Nothing Then
My.Settings.md5_hashes = New System.Collections.Specialized.StringCollection()
End If
Dim index As Integer = My.Settings.md5_hashes.IndexOf(value)
If index <> -1 AndAlso (index + 1) < My.Settings.md5_hashes.Count Then
Return My.Settings.md5_hashes.Item(index + 1)
End If
Return ""
End Function

For Next or a different loop for URL Icon Load

I have an app that basically is a launcher for various web pages. I am trying to, OnLoad, to populate all the pictureBoxes in my form with the FavICON for each URL. 25 to be exact. Should I use a For and Next or some other kind of looping method? New to the looping part so all and any help is appreciated.
My code to load just one single PictureBox is the following:
Private Sub MainFormWPL_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Dim WebICON As New WebBrowser
MainURLLoader.Navigate(Label1.Text)
'URLText.Text = WebBrowser1.Url.ToString
Try
Dim url As Uri = New Uri(Label1.Text)
If url.HostNameType = UriHostNameType.Dns Then
Dim icon = "http://" & url.Host & "/favicon.ico"
Dim request As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create(icon)
Dim response As System.Net.HttpWebResponse = request.GetResponse()
Dim stream As System.IO.Stream = response.GetResponseStream
Dim favicon = Image.FromStream(stream)
PictureBox1.Image = favicon
Else
End If
Catch ex As Exception
End Try
End Sub
Assuming you have Label1 --> PictureBox1, all the way to Label25 --> PictureBox25:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim matches() As Control
For i As Integer = 1 To 25
matches = Me.Controls.Find("Label" & i, True)
If matches.Length > 0 Then
Dim website As String = matches(0).Text
matches = Me.Controls.Find("PictureBox" & i, True)
If matches.Length > 0 AndAlso TypeOf matches(0) Is PictureBox Then
Dim PB As PictureBox = DirectCast(matches(0), PictureBox)
Task.Run(New Action(Sub() GetFavIcon(website, PB)))
End If
End If
Next
End Sub
Private Sub GetFavIcon(ByVal website As String, ByVal PB As PictureBox)
Dim url As Uri = New Uri(website)
If url.HostNameType = UriHostNameType.Dns Then
Dim icon = "http://" & url.Host & "/favicon.ico"
Dim request As System.Net.HttpWebRequest = System.Net.HttpWebRequest.Create(icon)
Dim response As System.Net.HttpWebResponse = request.GetResponse()
Dim stream As System.IO.Stream = response.GetResponseStream
Dim favicon = Image.FromStream(stream)
PB.Invoke(New MethodInvoker(Sub() PB.Image = favicon))
response.Close()
End If
End Sub
End Class

Multi threading webrequests?

I'm programming a tool that'll go through a lot of websites and see if they contain a text that's in a textbox.
Now I wan't to add multi threading so it goes quite a lot faster, most preferably I'd dynamically add threads.
This is my code now but it didn't work because it says index ouf of range. And I doubt it work anyways.
Dim clsThreads As New Generic.List(Of System.Threading.Thread)
Dim numberOfthreads As Integer = 1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For Each strLine1 As String In TextBox1.Text.Split({vbCr, vbLf}, StringSplitOptions.RemoveEmptyEntries)
For Each strLine2 As String In TextBox2.Text.Split({vbCr, vbLf}, StringSplitOptions.RemoveEmptyEntries)
clsThreads(numberOfthreads) = New Thread(Sub() Me.request(strLine1, strLine2))
clsThreads(numberOfthreads).Name = "Thread: " + numberOfthreads.ToString
clsThreads(numberOfthreads).IsBackground = True
clsThreads(numberOfthreads).Start()
numberOfthreads = numberOfthreads + 1
If (numberOfthreads.Equals(20)) Then
numberOfthreads = 0
End If
Next
Next
End Sub
So, how do I implement multi threading in a smart way?
This is my request sub:
Public Sub request(ByVal username, ByVal mail)
Dim req As WebRequest = WebRequest.Create("http://localhost/" + username)
req.Method = "GET"
Dim res As WebResponse = req.GetResponse()
Dim dataStream As Stream = res.GetResponseStream()
Dim reader As New StreamReader(dataStream)
Dim responseFromServer As String = reader.ReadToEnd()
If responseFromServer.Contains(mail) Then
TextBox3.Text = TextBox3.Text + vbNewLine + username
End If
End Sub
End Class
Something like this?
Option Strict On
Option Explicit On
Option Infer Off
Public Class Form1
Dim ActiveThreads As New List(Of System.Threading.Thread)
Delegate Sub delRemoveThread(thread As Threading.Thread)
Sub removeThread(thread As Threading.Thread)
If Me.InvokeRequired Then
Me.Invoke(New delRemoveThread(AddressOf removeThread), thread)
Else
ActiveThreads.Remove(thread)
End If
End Sub
Private Sub Button1_Click3(sender As Object, e As EventArgs) Handles Button1.Click
For i As Integer = 1 To 20
Dim th As New Threading.Thread(New Threading.ParameterizedThreadStart(Sub()
request("username", "mail")
removeThread(Threading.Thread.CurrentThread)
End Sub))
th.Start()
Next
End Sub
Public Sub request(ByVal username As String, ByVal mail As String)
Dim req As Net.WebRequest = Net.WebRequest.Create("http://localhost/" + username)
req.Method = "GET"
Dim res As Net.WebResponse = req.GetResponse()
Dim dataStream As IO.Stream = res.GetResponseStream()
Dim reader As New IO.StreamReader(dataStream)
Dim responseFromServer As String = reader.ReadToEnd()
If responseFromServer.Contains(mail) Then
TextBox3.Text = TextBox3.Text + vbNewLine + username
End If
End Sub
End Class

Bind a PictureBox to DataColum in VB.NET

I have a data repeater that contains a PictureBox and the picture needs to be fetched from a webserver. I already have a function that downloads the image, but the binding does not seem to be working. I am quite new to using windows forms and I am not too sure what I am doing wrong.
I have tried using a gridview, and I can confirm that that does show the images.
Public Function DlImg(ByVal _URL As String) As Byte()
Dim _tmpImage As Image = Nothing
Dim BytesOut As Byte()
Try
Dim _HttpWebRequest As System.Net.HttpWebRequest = DirectCast(System.Net.HttpWebRequest.Create(_URL), System.Net.HttpWebRequest)
_HttpWebRequest.AllowWriteStreamBuffering = True
Dim _WebResponse As System.Net.WebResponse = _HttpWebRequest.GetResponse():
Dim _WebStream As System.IO.Stream = _WebResponse.GetResponseStream()
_tmpImage = Image.FromStream(_WebStream)
_WebResponse.Close()
Using picture As Image = _tmpImage
Using stream As New IO.MemoryStream
picture.Save(stream, Imaging.ImageFormat.Jpeg)
BytesOut = stream.GetBuffer()
End Using
End Using
Catch _Exception As Exception
Return Nothing
End Try
Return BytesOut
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ListData.Columns.Add("Image", Type.GetType("System.Byte[]"))
For Each row As DataRow In ListData.Rows
row("Image") = DlImg("http://rental.joshblease.co.uk/propertyimages/p184js94kv1qco1e1e1jt71ouv11lm6.jpg")
Next row
ImgListItem.DataBindings.Add("Image", ListData, "Image", True)
DataGridView1.DataSource = ListData
DataRepeater1.DataSource = ListData
End Sub

Measuring download speed

I'm downloading a file using the following:
Dim client As WebClient = New WebClient()
client.DownloadFileAsync(New Uri("http://cachefly.cachefly.net/100mb.test"), "C:\Users\Dir\100mb.test")
The file downloads and saves into the C://Users/Dir/100mb.test, but while its downloading I would like to display the download speed in a label. How can I do this? I have read many tutorials, but most of them doesn't works or are outdated. I'm a newbie with vb.net, so I can't really write something on my own, could you give me any solutions?
May I suggest something different?
Imports System.Net
Public Class Form1
Private tmp = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Temp, "snafu.fubar")
Private Downloading As Boolean = False
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Downloading Then Exit Sub
Downloading = True
Dim wc As New WebClient
AddHandler wc.DownloadProgressChanged, AddressOf wc_ProgressChanged
AddHandler wc.DownloadFileCompleted, AddressOf wc_DownloadDone
wc.DownloadFileAsync(New Uri("http://cachefly.cachefly.net/100mb.test"), tmp, Stopwatch.StartNew)
End Sub
Private Sub wc_DownloadDone(sender As Object, e As System.ComponentModel.AsyncCompletedEventArgs)
Downloading = False
End Sub
Private Sub wc_ProgressChanged(sender As Object, e As DownloadProgressChangedEventArgs)
Me.Label1.Text = (e.BytesReceived / (DirectCast(e.UserState, Stopwatch).ElapsedMilliseconds / 1000.0#)).ToString("#")
End Sub
End Class
Because it makes no sense to determine the speed by the last chunk of bytes received, but instead you measure the total number of bytes and divide by the TOTAL time. Passing a stopwatch instance to the eventhandler has the advantage that it doesnt 'spoil' your class code - it''s visible only where it's needed.
This will give you percentage in the mean time. You could probably calculate from the percentage given a start time using DateTime.Now the speed in which it the download is taking:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Try
Dim client As WebClient = New WebClient()
AddHandler client.DownloadProgressChanged, AddressOf ProgChanged
client.DownloadFileAsync(New Uri("http://cachefly.cachefly.net/100mb.test"), "C:\Users\Dir\100mb.test")
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub ProgChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)
Dim progressPercentage As Integer = e.ProgressPercentage
End Sub
Define globals:
Dim lastUpdate As DateTime
Dim lastBytes As Long = 0
You'll need to assign an Event for progress:
Dim client As WebClient = New WebClient()
client.DownloadFileAsync(New Uri("http://cachefly.cachefly.net/100mb.test"), "C:\Users\Dir\100mb.test")
client.DownloadProgressChanged += Function(sender, e) progressChanged(e.BytesReceived)
The Event:
Private Sub progressChanged(bytes As Long)
If lastBytes = 0 Then
lastUpdate = DateTime.Now
lastBytes = bytes
Return
End If
Dim now = DateTime.Now
Dim timeSpan = now - lastUpdate
If Not timeSpan.Seconds = 0
Dim bytesChange = bytes - lastBytes
Dim bytesPerSecond = bytesChange / timeSpan.Seconds
lastBytes = bytes
lastUpdate = now
End If
End Sub
And you have the calculations of bytes per second.
label.Text = bytesPerSecond.ToString() + "B/s";
Try this:
Try this only when you're downloading through a backgroundworker
Private Sub worker_DoWork(Byval sender As Object, Byval e As DoWorkEventArgs)
Dim req As WebRequest = WebRequest.Create(downloadUrl) 'Make a request for the url of the file to be downloaded
Dim resp As WebResponse = req.GetResponse 'Ask for the response
Dim fs As New FileStream(path to download to, FileMode.CreateNew) 'Create a new FileStream that writes to the desired download path
Dim buffer(8192) As Byte 'Make a buffer
Dim downloadedsize As Long = 0
Dim downloadedTime As Long = 0
Dim dlSpeed As Long = 0
Dim currentSize As Long = 0 'Size that has been downloaded
Dim totalSize As Long = req.ContentLength 'Total size of the file that has to be downloaded
Do While currentSize < totalSize
Dim read As Integer = resp.GetResponseStream.Read(buffer, 0, 8192) 'Read the buffer from the response the WebRequest gave you
fs.Write(buffer, 0, read) 'Write to filestream that you declared at the beginning of the DoWork sub
currentSize += read
downloadedSize += read
downloadedTime += 1 'Add 1 millisecond for every cycle the While field makes
If downloadedTime = 1000 Then 'Then, if downloadedTime reaches 1000 then it will call this part
dlSpeed = (downloadedSize / TimeSpan.FromMilliseconds(downloadedTime).TotalSeconds) 'Calculate the download speed by dividing the downloadedSize by the total formatted seconds of the downloadedTime
downloadedTime = 0 'Reset downloadedTime and downloadedSize
downloadedSize = 0
End If
End While
fs.Close() 'Close the FileStream first, or the FileStream will crash.
resp.Close() 'Close the response
End Sub
Sorry for not using proper formatting, but this is a solution in itself.