Question TCP Remote File Transfer?????

SteboCSC

Member
Joined
Aug 11, 2009
Messages
10
Programming Experience
Beginner
I'm trying to create a tcp server and tcp client using sockets. I'm new to VB and could use some help. I have the file transfer part working but, I'm running into an issue. Every time I transfer a file remotely the file size changes, leaving the file unusable. Can somebody please help! Here is the source code for the client and server........

-CLIENT-

Imports System.Threading
Imports System.Net.Sockets
Imports System.Net
Imports System.Text
Imports System.IO

Public Class Form1
Inherits System.Windows.Forms.Form

Private Sub btnBrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBrowse.Click
OpenFileDialog.ShowDialog()
tbFilename.Text = OpenFileDialog.FileName
End Sub

Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click


Dim filebuffer As Byte()
Dim filestream As Stream
filestream = File.OpenRead(tbFilename.Text)
ReDim filebuffer(filestream.Length)

filestream.Read(filebuffer, 0, filestream.Length)

Dim len As Long = filestream.Length - 1
For i As Long = 0 To len
If i Mod 1000 = 0 Then 'only update UI every 1 Kb copied
ProgressBar1.Value = i * 100 / len
Application.DoEvents()
End If
Next
ProgressBar1.Value = 0
Dim IpHost As IPHostEntry
IpHost = Dns.GetHostByName(tbServer.Text)
Dim clientSocket As New TcpClient(tbServer.Text.ToString, 1234)

Dim networkStream As NetworkStream
networkStream = clientSocket.GetStream()
networkStream.write(filebuffer, 0, filestream.Length)

End Sub

End Class



-SERVER-

Imports System.Threading
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.IO


Public Class Form1
Inherits System.Windows.Forms.Form

Dim test = System.Net.IPAddress.Any
Private alSockets As ArrayList


Public Sub listenerThread()
Const portNumber As Integer = 1234
Dim tcpListener As New TcpListener(test, portNumber)
Dim handlerSocket As Socket
Dim thdstHandler As ThreadStart
Dim thdHandler As Thread

tcpListener.Start()
Do
handlerSocket = tcpListener.AcceptSocket()
If handlerSocket.Connected Then
lbConnections.Items.Add( _
handlerSocket.RemoteEndPoint.ToString() + _
" Connected.")
SyncLock (Me)
alSockets.Add(handlerSocket)
End SyncLock
thdstHandler = New ThreadStart(AddressOf _
HandlerThread)
thdHandler = New Thread(thdstHandler)
thdHandler.Start()

End If
Loop
End Sub

Public Sub HandlerThread()

Dim handlerSocket As Socket
handlerSocket = alSockets(alSockets.Count - 1)
Dim networkStream As NetworkStream = New _
NetworkStream(handlerSocket)
Dim blockSize As Int16 = 1024
Dim thisRead As Int16
Dim dataByte(blockSize) As Byte

SyncLock Me

Dim SaveFileName As String = String.Empty
Dim DialogSave As New SaveFileDialog
DialogSave.Filter = "All files (*.*)|*.*"
DialogSave.RestoreDirectory = True
DialogSave.Title = "Where do you want to save the file?"
DialogSave.InitialDirectory = "C:/"
If DialogSave.ShowDialog() = DialogResult.OK Then
SaveFileName = DialogSave.FileName
End If

Dim filestream As Stream
filestream = File.OpenWrite(SaveFileName)

While (True)
thisRead = networkStream.Read(dataByte, _
0, blockSize)
If thisRead = 0 Then Exit While
filestream.Write(dataByte, 0, blockSize.ToString)
End While

filestream.Close()
End SyncLock
lbConnections.Items.Add("File Written")
handlerSocket = Nothing

End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim IpHost As IPHostEntry
IpHost = Dns.GetHostByName(Dns.GetHostName())
Label1.Text = "My IP Address Is " + _
IpHost.AddressList(0).ToString()
alSockets = New ArrayList
Dim thdListener As New Thread(New ThreadStart _
(AddressOf listenerThread))
thdListener.Start()
End Sub

End Class
 
Hello.

You're problem is most likely is this:
VB.NET:
While (True)
      thisRead = networkStream.Read(dataByte, 0, blockSize)
      If thisRead = 0 Then Exit While
      filestream.Write(dataByte, 0, blockSize.ToString)
End While

I still don't know why you can see such examples everywhere, since they _can_ work but are failing for the most time and especially with larger files. The problem is that your loop is way faster then the NetworkStream. So the NetworkStream reports that there's nothing more to read, buuuuuuut the underlaying connection has just nothing received to read _yet_. The slower your connection and the bigger your file is, the most likely it is that you run into this problem.

I've tried over and over to find a suitable solution to that problem without using Thread.Sleep($number), but I've only encountered two possiblities:
* Knowing when the stream ends, f.e. with a special Byte-Sequence (0,255,0,255,0,255)
* Knowing the file size of the received thing, f.e. sending it with the first 4(8 bytes or so.

Bobby

P.s.: Here' one of my topics which are covering, more or less, the same issue:
http://www.vbdotnetforums.com/net-sockets/35328-networkstream-large-amount-data.html
 
Last edited:
While (True)
thisRead = networkStream.Read(dataByte, 0, blockSize)
If thisRead = 0 Then Exit While
This can be used if the socket is open when starting to read and closing when all data is transmitted, because Read blocks on the open socket and returns 0 when it is closed.
But this part is wrong:
filestream.Write(dataByte, 0, blockSize)
It must be:
VB.NET:
filestream.Write(dataByte, 0, [COLOR="Green"]thisRead[/COLOR])
No Read call is guaranteed to return the number of bytes requested, but it will return some bytes up to that count, or 0.

Also Close when done:
VB.NET:
clientSocket.GetStream.[B]Close[/B]()
clientSocket.[B]Close[/B]()
VB.NET:
handlerSocket.[B]Close[/B]()
 
Thanks!

Thanks for the help! I thought it might be something simple! lol I've been going crazy trying to figure that out for the past week! Once again, Thanks!
 
This can be used if the socket is open when starting to read and closing when all data is transmitted, because Read blocks on the open socket and returns 0 when it is closed.

Yeah, sure...but I always had the problem that if the Read() runs into the timeout that it is killing my whole connection (which is not really helpful if you've something with a session). Means it seems like that he block up till the timeout and then ends the connection.

And you're right, sorry, I've somehow mistaken that one for the same as DataAvalaible or Avalaible. :eek:

Bobby
 
Robert_Zenz said:
Read() runs into the timeout that it is killing my whole connection
In this case that won't happen. Default read timeout is infinite, and the sender here continuously writes bytes, so even with a very slow connection the Read will at least get one byte each call. This happens until the whole file is transmitted and sender closes connection, then reader gets the 0 return value and closes also.
 
Back
Top