Re: Simple TCP Socket Communicator - Please Help



Hi Tomasz,

I'm glad that you've figured out the new problem. Just some further
comments to the read/write question you mentioned

Sure, I think it's supported to read/write in separate thread. Actually,
just like what you can do in unmanaged socket application, you can create
different thread to processing data and read/write via the same socket
object. And the data read from socket and write into socket are actually
managed through another underlying buffer(received buffer and send buffer),
data you read from won't affect data you write into wire

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msdnmg@xxxxxxxxxxxxxx

This posting is provided "AS IS" with no warranties, and confers no rights.

--------------------
From: "Tomasz J" <oegweb@xxxxxxxxxxxxx>
Subject: Re: Simple TCP Socket Communicator - Please Help
Date: Fri, 4 Apr 2008 23:52:33 +0200

OK, please disregard this message. I found the problem. My connection was
being closed by the remote host for a reason.
Thank you,
Thomas

"Tomasz J" <oegweb@xxxxxxxxxxxxx> wrote in message
news:%23GflIsklIHA.3940@xxxxxxxxxxxxxxxxxxxxxxx
Thank you for your response.

It seems that testing NetworkStream.DataAvailable before reading any
data
to the MemoryStream first and then, deserializing from the MemoryStream
using BinaryReader helps.

But right now I have at least one problem left: writing.
Writing to the NetworkStream using *reused* BinaryWriter occasionally I
receive:

System.IO.IOException - "Unable to write data to the transport
connection:
An established connection was aborted by the software in your host
machine."

So, according to this message it is my host who, for any reason, aborts
the connection.

What is the best way to write data in such scenario?
Remember that I read data in a loop on one thread but write from the
Windows application on another.
Is this permitted? I do not see any reason why not, since all reads and
writes are always performed on their respective, yet separate threads,
but
may be there are threading conflicts between writes and reads? I have no
idea. Should socket reads be synchronized with writes? Or, may be, the
problem is somewhere else.
Please advice. I already spent hours googling for some really good,
robust
examples, but found none - only very simplistic demos.

Thanks,

Thomas

"Steven Cheng [MSFT]" <stcheng@xxxxxxxxxxxxxxxxxxxx> wrote in message
news:4PAWkDhlIHA.9932@xxxxxxxxxxxxxxxxxxxxxxxxx
Hi tomasz,

From your description, you're encountering some error when using the
TcpClient to receive data from server, correct?

Since TcpClient work upon a physical Tcp connection, so you should
already
have a TcpListener or a TCp socket at another server, correct? Also,
based
on my local testing, such problem may due to the adapted Reader or
Writer
object that doesn't correctly fit the underlying transfered byte data in
socket buffer. I suggest you directly read the raw byte[] array from
the
NetWorkStream (copy it into buffer) and process them further. Also, in
your client reading loop, you can also first use
"NetworkStream.DataAvailable to check whether there is data ready for
read
in receive buffer.

here is a simple client app I've used for testing. also, In my read
method,
I simply try reading once, you can use a loop in a separate worker
thread
to do the same task:

====================================
public partial class Form1 : Form
{
private TcpClient _client;
private StreamReader _reader;
private StreamWriter _writer;
private NetworkStream _stream;
private byte[] buf;

public Form1()
{
InitializeComponent();
}

//create tcp client and connect server
private void button1_Click(object sender, EventArgs e)
{
_client = new TcpClient(AddressFamily.InterNetwork);
_client.Connect("localhost", 8989);

//_client.ConnectIPAddress.Loopback, 8989);
_stream = _client.GetStream();
buf = new byte[_client.ReceiveBufferSize];

_reader = new StreamReader(_stream);
_writer = new StreamWriter(_stream);
}

//read data from buffer if available(and decode it --string data)
private void button2_Click(object sender, EventArgs e)
{
int len;
if (_stream.DataAvailable)
{
len = _stream.Read(buf, 0, buf.Length);
if (len > 0)
textBox1.AppendText("\r\nreceived: " +
Encoding.UTF8.GetString(buf, 0, len));



}


}

//close connection
private void button3_Click(object sender, EventArgs e)
{
_reader.Close();
_writer.Close();
_client.Close();
}
}
================================

Hope this helps.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


Delighting our customers is our #1 priority. We welcome your comments
and
suggestions about how we can improve the support we provide to you.
Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msdnmg@xxxxxxxxxxxxxx

==================================================
Get notification to my posts through email? Please refer to

http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent
issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each
follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach
the
most efficient resolution. The offering is not appropriate for
situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are
best
handled working with a dedicated Microsoft Support Engineer by
contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no
rights.
--------------------
From: "Tomasz J" <oegweb@xxxxxxxxxxxxx>
Subject: Simple TCP Socket Communicator - Please Help
Date: Thu, 3 Apr 2008 14:06:49 +0200


Hello developers,



I am trying to create a simple TCP chat-like communicator.

It will communicate with one peer only sending and receiving messages on
the
same port. I guess, this requirement is important. Once the
communication
is
established it will not receive any other calls, so, I guess, I do not
have
to use TcpListener.



I created a TcpClient object. In a infinite a loop running on a
separate
thread I try to read incoming data using BinaryReader (cross-thread
communication is handled). Whenever I want to send a message I do it
synchronously on the main thread using the same TcpClient object and
BinaryWriter.



First of all, I am not sure if approach the problem the right way. This
is
my first application of that sort.



Second, trying to read incoming data often I receive exceptions like:

A first chance exception of type 'System.IO.EndOfStreamException'
occurred
in mscorlib.dll

at System.IO.__Error.EndOfFile()

at System.IO.BinaryReader.FillBuffer(Int32 numBytes)

at System.IO.BinaryReader.ReadUInt32()



Perhaps, I am doing something wrong.



Could anyone advise? Not sure if this is important: I use .Net Framework
3.5.

I will appreciate any hints.



Thomas





The code goes more or less like this:



TcpClient tcpClient = new TcpClient(AddressFamily.InterNetwork);

tcpClient.Connect(someEndPoint);

NetworkStream clientSockStream = tcpClient.GetStream();

BinaryReader reader = new BinaryReader(clientSockStream);

BinaryWriter writer = new BinaryWriter(clientSockStream);



Thread listenerThread;

listenerThread = new Thread(new ThreadStart(ListenToPeer));

listenerThread.Start();



void SendSomeData(int myData) {

writer.Wtite(myData);

}



void ListenToPeer()

{

while(true) {

int data = reader.ReadInt32();

// process data here

}

}










.