468,720 Members | 1,485 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,720 developers. It's quick & easy.

TcpClient and images

Hi,

I'm writing a client/server application in which the client send a series of
screenshots to the server to be saved using the tcpclient.
in most cases the first screenshot is transmitted ok and arrives at the
server but from after that i only a couple of KB from the start of the file
which cases the picture to display only the very top (of the screen).
All the pictures are saved at the client side before sent to the server and
they are always good and "full", so the problems seem to be from the
transmition part or after that.

please help ...
****** Server Code:
Const portNo As Integer = 8080
Dim localAdd As System.Net.IPAddress = System.Net.IPAddress.Any
Dim listener As New TcpListener(localAdd, portNo)
listener.Start()

Dim tcpClient As TcpClient

tcpClient = listener.AcceptTcpClient()

tcpClient.ReceiveBufferSize = 400000

Dim lingerOption As New LingerOption(True, 10)
tcpClient.LingerState = lingerOption

Dim NWStream As NetworkStream = tcpClient.GetStream

Dim bytesToRead(200000) As Byte
Dim numBytesRead As Integer = 0

'---read incoming stream
If NWStream.CanRead Then
Do
numBytesRead = numBytesRead + NWStream.Read(bytesToRead,
numBytesRead, tcpClient.ReceiveBufferSize)
Loop While NWStream.DataAvailable
NWStream.Close()
End If

Dim FileName = DateTimeForFile() & ".jpg"
Dim fs As System.IO.FileStream
fs = New System.IO.FileStream(FileName,
System.IO.FileMode.Create, _
System.IO.FileAccess.Write)
fs.Write(bytesToRead, 0, numBytesRead)
fs.Close()

MsgBox(numBytesRead)

tcpClient.Close()

listener.Stop()
****** Client Code:
Dim FileName = DateTimeForFile() & ".jpg"
< Code to save the screenshot on the client>
Dim tcpClient As New System.Net.Sockets.TcpClient
tcpClient.Connect(Me.TextBox_Server.Text, portNo)
Dim NWStream As NetworkStream = tcpClient.GetStream
Dim fs As FileStream
fs = New FileStream(FileName, FileMode.Open, FileAccess.Read)
Dim bytesToSend(fs.Length) As Byte
Dim numBytesRead As Integer = fs.Read(bytesToSend, 0,
bytesToSend.Length)
fs.Close()
NWStream.Write(bytesToSend, 0, numBytesRead)
tcpClient.Close()
Aug 17 '05 #1
3 2728
Hi!

There are three things i found in your code which could be related to your
problem.

1. On the client side you try to read the whole file content in one call to
the Stream.Read method. It is not guaranteed, that the whole data block is
read at once (I think that's even true for FileStream). You should examine
the number of bytes actually read and retry reading until the whole file has
been read.

2. If you read the data comming from the network faster then it arrives,
then I think that NetworkStream.DataAvailable can return false even if
further data will be received. Have you thought about sending some sort of
header with each image, containing the actual image size?

3. In applications that maintain multiple open NetworkStreams I observed
that setting receive buffers above a specific size resulted in blocking
streams. No data could be received at all. The threshold I found was
somewhere at 80KB (as far as I remember) for the sum of all NetworkStream
receive buffers. I'm not sure whether (and in fact I don't think that) this
also is an issue with a single connection but nevertheless you could try to
reduce your receive-bfufer size.

Cheers
- Markus

"?????" <@discussions.microsoft.com> schrieb im Newsbeitrag
news:94**********************************@microsof t.com...
Hi,

I'm writing a client/server application in which the client send a series
of
screenshots to the server to be saved using the tcpclient.
in most cases the first screenshot is transmitted ok and arrives at the
server but from after that i only a couple of KB from the start of the
file
which cases the picture to display only the very top (of the screen).
All the pictures are saved at the client side before sent to the server
and
they are always good and "full", so the problems seem to be from the
transmition part or after that.

please help ...
****** Server Code:
Const portNo As Integer = 8080
Dim localAdd As System.Net.IPAddress = System.Net.IPAddress.Any
Dim listener As New TcpListener(localAdd, portNo)
listener.Start()

Dim tcpClient As TcpClient

tcpClient = listener.AcceptTcpClient()

tcpClient.ReceiveBufferSize = 400000

Dim lingerOption As New LingerOption(True, 10)
tcpClient.LingerState = lingerOption

Dim NWStream As NetworkStream = tcpClient.GetStream

Dim bytesToRead(200000) As Byte
Dim numBytesRead As Integer = 0

'---read incoming stream
If NWStream.CanRead Then
Do
numBytesRead = numBytesRead +
NWStream.Read(bytesToRead,
numBytesRead, tcpClient.ReceiveBufferSize)
Loop While NWStream.DataAvailable
NWStream.Close()
End If

Dim FileName = DateTimeForFile() & ".jpg"
Dim fs As System.IO.FileStream
fs = New System.IO.FileStream(FileName,
System.IO.FileMode.Create, _
System.IO.FileAccess.Write)
fs.Write(bytesToRead, 0, numBytesRead)
fs.Close()

MsgBox(numBytesRead)

tcpClient.Close()

listener.Stop()
****** Client Code:
Dim FileName = DateTimeForFile() & ".jpg"
< Code to save the screenshot on the client>
Dim tcpClient As New System.Net.Sockets.TcpClient
tcpClient.Connect(Me.TextBox_Server.Text, portNo)
Dim NWStream As NetworkStream = tcpClient.GetStream
Dim fs As FileStream
fs = New FileStream(FileName, FileMode.Open, FileAccess.Read)
Dim bytesToSend(fs.Length) As Byte
Dim numBytesRead As Integer = fs.Read(bytesToSend, 0,
bytesToSend.Length)
fs.Close()
NWStream.Write(bytesToSend, 0, numBytesRead)
tcpClient.Close()

Aug 17 '05 #2
1. I've checked the reading of the file and saw that always to read command
reads the whole file in one call.
2. I tried to limit the reading from the stream based on the file size and
not by the dataavailble property and that fixes the problem - but i don't
know how to send the file size from the client to the server ?

"Markus Minichmayr" wrote:
Hi!

There are three things i found in your code which could be related to your
problem.

1. On the client side you try to read the whole file content in one call to
the Stream.Read method. It is not guaranteed, that the whole data block is
read at once (I think that's even true for FileStream). You should examine
the number of bytes actually read and retry reading until the whole file has
been read.

2. If you read the data comming from the network faster then it arrives,
then I think that NetworkStream.DataAvailable can return false even if
further data will be received. Have you thought about sending some sort of
header with each image, containing the actual image size?

3. In applications that maintain multiple open NetworkStreams I observed
that setting receive buffers above a specific size resulted in blocking
streams. No data could be received at all. The threshold I found was
somewhere at 80KB (as far as I remember) for the sum of all NetworkStream
receive buffers. I'm not sure whether (and in fact I don't think that) this
also is an issue with a single connection but nevertheless you could try to
reduce your receive-bfufer size.

Cheers
- Markus

"?????" <@discussions.microsoft.com> schrieb im Newsbeitrag
news:94**********************************@microsof t.com...
Hi,

I'm writing a client/server application in which the client send a series
of
screenshots to the server to be saved using the tcpclient.
in most cases the first screenshot is transmitted ok and arrives at the
server but from after that i only a couple of KB from the start of the
file
which cases the picture to display only the very top (of the screen).
All the pictures are saved at the client side before sent to the server
and
they are always good and "full", so the problems seem to be from the
transmition part or after that.

please help ...
****** Server Code:
Const portNo As Integer = 8080
Dim localAdd As System.Net.IPAddress = System.Net.IPAddress.Any
Dim listener As New TcpListener(localAdd, portNo)
listener.Start()

Dim tcpClient As TcpClient

tcpClient = listener.AcceptTcpClient()

tcpClient.ReceiveBufferSize = 400000

Dim lingerOption As New LingerOption(True, 10)
tcpClient.LingerState = lingerOption

Dim NWStream As NetworkStream = tcpClient.GetStream

Dim bytesToRead(200000) As Byte
Dim numBytesRead As Integer = 0

'---read incoming stream
If NWStream.CanRead Then
Do
numBytesRead = numBytesRead +
NWStream.Read(bytesToRead,
numBytesRead, tcpClient.ReceiveBufferSize)
Loop While NWStream.DataAvailable
NWStream.Close()
End If

Dim FileName = DateTimeForFile() & ".jpg"
Dim fs As System.IO.FileStream
fs = New System.IO.FileStream(FileName,
System.IO.FileMode.Create, _
System.IO.FileAccess.Write)
fs.Write(bytesToRead, 0, numBytesRead)
fs.Close()

MsgBox(numBytesRead)

tcpClient.Close()

listener.Stop()
****** Client Code:
Dim FileName = DateTimeForFile() & ".jpg"
< Code to save the screenshot on the client>
Dim tcpClient As New System.Net.Sockets.TcpClient
tcpClient.Connect(Me.TextBox_Server.Text, portNo)
Dim NWStream As NetworkStream = tcpClient.GetStream
Dim fs As FileStream
fs = New FileStream(FileName, FileMode.Open, FileAccess.Read)
Dim bytesToSend(fs.Length) As Byte
Dim numBytesRead As Integer = fs.Read(bytesToSend, 0,
bytesToSend.Length)
fs.Close()
NWStream.Write(bytesToSend, 0, numBytesRead)
tcpClient.Close()


Aug 19 '05 #3
In your scenario the easiest way to do this is to use System.IO.BinaryWriter
and System.IO.BinaryReader. Do something like the following (C# Syntax):

Sender:
....
using (BinaryWriter imageWriter = new BinaryWriter(outputStream))
{
imageWriter.Write((uint) MagicNumber); // You should use a magic
number to detect communication errors
imageWriter.Write((uint) ProtocolVersion); // You might want to
include a version number of your protocol
imageWriter.Write((int) imageBytes.Length); // Write the image size
imageWriter.Write(imageBytes); // Write the actual
image
}
....
Receiver:

....
byte[] imageBytes;

using (BinaryReader imageReader = new BinaryReader(inputStream))
{
uint magicNumber = imageReader.ReadUInt32();
uint protocolVersion = imageReader.ReadUInt32();

... check magic number and protocol version and do error handling ...

int imageSize = imageReader.ReadInt32();
imageBytes = imageReader.ReadBytes(imageSize); // The full
data block will be read here.
}

.... do whatever you want ...
Don't forget to handle communication errors like timeouts!

- Markus
"?????" <@discussions.microsoft.com> schrieb im Newsbeitrag
news:EA**********************************@microsof t.com...
1. I've checked the reading of the file and saw that always to read
command
reads the whole file in one call.
2. I tried to limit the reading from the stream based on the file size and
not by the dataavailble property and that fixes the problem - but i don't
know how to send the file size from the client to the server ?

"Markus Minichmayr" wrote:
Hi!

There are three things i found in your code which could be related to
your
problem.

1. On the client side you try to read the whole file content in one call
to
the Stream.Read method. It is not guaranteed, that the whole data block
is
read at once (I think that's even true for FileStream). You should
examine
the number of bytes actually read and retry reading until the whole file
has
been read.

2. If you read the data comming from the network faster then it arrives,
then I think that NetworkStream.DataAvailable can return false even if
further data will be received. Have you thought about sending some sort
of
header with each image, containing the actual image size?

3. In applications that maintain multiple open NetworkStreams I observed
that setting receive buffers above a specific size resulted in blocking
streams. No data could be received at all. The threshold I found was
somewhere at 80KB (as far as I remember) for the sum of all NetworkStream
receive buffers. I'm not sure whether (and in fact I don't think that)
this
also is an issue with a single connection but nevertheless you could try
to
reduce your receive-bfufer size.

Cheers
- Markus

"?????" <@discussions.microsoft.com> schrieb im Newsbeitrag
news:94**********************************@microsof t.com...
> Hi,
>
> I'm writing a client/server application in which the client send a
> series
> of
> screenshots to the server to be saved using the tcpclient.
> in most cases the first screenshot is transmitted ok and arrives at the
> server but from after that i only a couple of KB from the start of the
> file
> which cases the picture to display only the very top (of the screen).
> All the pictures are saved at the client side before sent to the server
> and
> they are always good and "full", so the problems seem to be from the
> transmition part or after that.
>
> please help ...
>
>
> ****** Server Code:
> Const portNo As Integer = 8080
> Dim localAdd As System.Net.IPAddress = System.Net.IPAddress.Any
> Dim listener As New TcpListener(localAdd, portNo)
> listener.Start()
>
> Dim tcpClient As TcpClient
>
> tcpClient = listener.AcceptTcpClient()
>
> tcpClient.ReceiveBufferSize = 400000
>
> Dim lingerOption As New LingerOption(True, 10)
> tcpClient.LingerState = lingerOption
>
> Dim NWStream As NetworkStream = tcpClient.GetStream
>
> Dim bytesToRead(200000) As Byte
> Dim numBytesRead As Integer = 0
>
> '---read incoming stream
> If NWStream.CanRead Then
> Do
> numBytesRead = numBytesRead +
> NWStream.Read(bytesToRead,
> numBytesRead, tcpClient.ReceiveBufferSize)
> Loop While NWStream.DataAvailable
> NWStream.Close()
> End If
>
> Dim FileName = DateTimeForFile() & ".jpg"
> Dim fs As System.IO.FileStream
> fs = New System.IO.FileStream(FileName,
> System.IO.FileMode.Create, _
> System.IO.FileAccess.Write)
> fs.Write(bytesToRead, 0, numBytesRead)
> fs.Close()
>
> MsgBox(numBytesRead)
>
> tcpClient.Close()
>
> listener.Stop()
>
>
> ****** Client Code:
> Dim FileName = DateTimeForFile() & ".jpg"
> < Code to save the screenshot on the client>
> Dim tcpClient As New System.Net.Sockets.TcpClient
> tcpClient.Connect(Me.TextBox_Server.Text, portNo)
> Dim NWStream As NetworkStream = tcpClient.GetStream
> Dim fs As FileStream
> fs = New FileStream(FileName, FileMode.Open, FileAccess.Read)
> Dim bytesToSend(fs.Length) As Byte
> Dim numBytesRead As Integer = fs.Read(bytesToSend, 0,
> bytesToSend.Length)
> fs.Close()
> NWStream.Write(bytesToSend, 0, numBytesRead)
> tcpClient.Close()


Aug 19 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Daniel | last post: by
2 posts views Thread by Theo | last post: by
3 posts views Thread by Ricardo Quintanilla | last post: by
3 posts views Thread by Danny Tuppeny | last post: by
reply views Thread by Torsten Brasch | last post: by
3 posts views Thread by מורדי | last post: by
5 posts views Thread by puzzlecracker | last post: by
1 post views Thread by Oskars | last post: by
9 posts views Thread by bryonone | last post: by
reply views Thread by zhoujie | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.