TCP listener

M

Markgoldin

Here is my code to create a TCP listener:
file name DataAdapterLauncher.cs
public static TcpListener tcpl;
IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 1024);//listen
on all local addresses
tcpl = new TcpListener(ipe);
tcpl.Stop();
tcpl.Start();
and that code handles data:
file name DataAdapterLauncher.cs
private volatile bool monitorPort = true;
byte[] byteReadStream = null; // holds the data in byte buffer
TcpClient tcpc = DataAdapterLauncher.tcpl.AcceptTcpClient(); //accept
connection
while (monitorPort)
{
byteReadStream = new byte[tcpc.Available]; //allocate space for data
tcpc.GetStream().Read(byteReadStream, 0, tcpc.Available);
//read data into byte array
if (byteReadStream != null)
{
monitorPort = false;
}
}
Please note, I am not a .Net developer, so you might see something strange
in my code.
It does work though but with one problem, as soon as a client disconnects
from my listener, the CPU usage goes up 100% to my exe
and no connections can be made to it.
Any idea?

Thanks for any help.
 
I

Ignacio Machin ( .NET/ C# MVP )

tcpl = new TcpListener(ipe);
tcpl.Stop();

Why the Stop?
tcpl.Start();
TcpClient tcpc = DataAdapterLauncher.tcpl.AcceptTcpClient(); //accept
connection

How do you return to the above line?
If you never do, you can only create one connection

I posted code a time ago about how to get a multi connection server.
This is a part of that thread:


Its very easy, you have a thread just receiving connections in a loop
and
inserting the connections in a queue and then spawning a new thread

while(true)
{
Socket s = listener1.AcceptSocket();
syncedQueue.Enqueue( s );
new Thread( new ThreadStart( workerMethod) ).Start();
}

workerMethod()
{
Socket s = syncedQueue.Dequeue();
}

You have to use a synced queue though:

syncedqueue = Queue.Synchonize( new Queue() );
 
M

Markgoldin

Like I said, I am not a c# programmer, but I need a little c# code for my
application.
I understand your commens though and will look into it.
But for now it's fine with one connection only however the following
How do you return to the above line?
If you never do, you can only create one connection

is the reason of CPU going 100% after a client closes connection?

message
 
I

Ignacio Machin ( .NET/ C# MVP )

Like I said, I am not a  c# programmer, but I need a little c# code formy
application.
I understand your commens though and will look into it.
But for now it's fine with one connection only however the following

 >> TcpClient tcpc = DataAdapterLauncher.tcpl.AcceptTcpClient(); //accept


is the reason of CPU going 100% after a client closes connection?

no, of course not, that line is executed AT the connection time, then
you enter in the while loop
do this, copy your code in a win or console project and see where it
gets stuck
 
M

Markgoldin

Here is my modified code:
while (monitorPort)
{
byteReadStream = new byte[tcpc.Available]; //allocate space for data
tcpc.GetStream().Read(byteReadStream, 0, tcpc.Available);
//read data into byte array
if (byteReadStream != null)
{
monitorPort = false;
}
System.Console.WriteLine("In the loop");
}

The change is
System.Console.WriteLine("In the loop");

When I send data to the listener I see "In the loop" two times, after
disconnecting in starts writing "In the loop" without stoping.

Any idea why it gets into the loop after disconnecting?

message
Like I said, I am not a c# programmer, but I need a little c# code for my
application.
I understand your commens though and will look into it.
But for now it's fine with one connection only however the following


is the reason of CPU going 100% after a client closes connection?

no, of course not, that line is executed AT the connection time, then
you enter in the while loop
do this, copy your code in a win or console project and see where it
gets stuck
 
M

Markgoldin

Ok, valid point.

private volatile bool go = true;
private volatile bool monitorPort = true;

byte[] byteReadStream = null;
TcpClient tcpc = DataAdapterLauncher.tcpl.AcceptTcpClient(); //accept
connection
while (go)
{
while (monitorPort)
{
byteReadStream = new byte[tcpc.Available]; //allocate space for data
tcpc.GetStream().Read(byteReadStream, 0, tcpc.Available);
//read data into byte array
if (byteReadStream != null)
{
monitorPort = false;
}
System.Console.WriteLine("In the loop");
}
string str;
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
str = enc.GetString(byteReadStream);
monitorPort = true;
}

It works fine as long as a client keeps connection.


Peter Duniho said:
[...]
It does work though but with one problem, as soon as a client disconnects
from my listener, the CPU usage goes up 100% to my exe
and no connections can be made to it.
Any idea?

Not really. You didn't post a concise-but-complete code sample, so
there's no telling what in your code might be stuck in a loop.

That said, it's certainly possible that the loop you posted for some
reason turns out to be the problem. I admit, from the code you posted
it's not clear why your loop works at all (when would "byteReadStream"
ever _not_ be null?). But assuming there's some condition under which
you're not exiting the loop, it wouldn't surprise me to find that you wind
up consuming 100% CPU, because it's probably a scenario in which no
progress towards exiting the loop is made.

You shouldn't be using the Available property anyway. It's not a reliable
indicator of what you can read. But without a complete code sample, it's
not really possible to offer more detailed advice as to how to fix your
program.

Pete
 
M

Markgoldin

<TcpClient.Available property
Yes, I am working on that and on other comments that have been made here.
< how do you expect to exit out of the "go" loop?
This loop is required because of the main purpose of the program I am trying
to adapt.
This is a push server. This product can communicate with .Net code and push
data to the browser from it.
Since my main coding environment is not .Net I am trying to talk to .Net
piece to provide data to be pushed.
One of ideas is to use TCP sockets for that.
So, I am using the push server product's .Net sample and trying to modify it
to aceept external data.
Like I said, it besically works. But now when I am testing the whole thing I
have noticed
that it only works untill I close connection to the c# listener.


Ok, valid point.

private volatile bool go = true;
private volatile bool monitorPort = true;

byte[] byteReadStream = null;
TcpClient tcpc = DataAdapterLauncher.tcpl.AcceptTcpClient(); //accept
connection
while (go)
{
while (monitorPort)
{
byteReadStream = new byte[tcpc.Available]; //allocate space for data
tcpc.GetStream().Read(byteReadStream, 0, tcpc.Available);
//read data into byte array
if (byteReadStream != null)
{
monitorPort = false;
}
System.Console.WriteLine("In the loop");
}
string str;
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
str = enc.GetString(byteReadStream);
monitorPort = true;
}

It works fine as long as a client keeps connection.

That's still not a complete code sample. And it raises more questions
than it answers. For example:

-- why do you have the "monitorPort" loop at all? assuming that's the
literal code, "byteReadStream" is _never_ going to be null, and so that
loop will always execute the contained block exactly once before exiting

-- why do you decode the bytes you read? you never use the "str"
variable for anything once it's been assigned

-- how do you expect to exit out of the "go" loop? the variable "go"
is initialized to "true" and then never modified

-- in what context does that code appear? what do you expect to
happen when the connection is closed?

Also, as I mentioned before, you _really_ should not be using the
TcpClient.Available property. That said, if you insist, you definitely
should not be passing it as the length parameter for the Stream.Read()
method. It could change between the time you allocate the buffer and the
time you call the Read() method. Just pass "byteReadStream.Length"
instead.

Again, based on the code posted, I'm not surprised your program gets stuck
in an endless, non-yielding loop. That's just what the code you posted
looks like it would do. My guess is that if you fix your code to break
out of the loop when the connection is closed, your problem would go
away. But you would continue to have other the flaws in your code, and
you should really be looking to fix those too.

Pete
 
B

Boaz Ben-Porat

I didn't test it, but I believe the problem is an infinite loop without wait
state.
This code is an infinite loop of a call to a blocking Stream.Read()
(actually a TCP receive()). As long as the connection is alive, the Read()
shall block execution of yor application most of the time.
When the connection is closed, Read() returnes immediately, so the loop is
executed non-stop and occupies 100% CPU.

Boaz Ben-Porat
Milestone Systems A/S
Denmark


Markgoldin said:
Ok, valid point.

private volatile bool go = true;
private volatile bool monitorPort = true;

byte[] byteReadStream = null;
TcpClient tcpc = DataAdapterLauncher.tcpl.AcceptTcpClient(); //accept
connection
while (go)
{
while (monitorPort)
{
byteReadStream = new byte[tcpc.Available]; //allocate space for data
tcpc.GetStream().Read(byteReadStream, 0, tcpc.Available);
//read data into byte array
if (byteReadStream != null)
{
monitorPort = false;
}
System.Console.WriteLine("In the loop");
}
string str;
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
str = enc.GetString(byteReadStream);
monitorPort = true;
}

It works fine as long as a client keeps connection.


Peter Duniho said:
[...]
It does work though but with one problem, as soon as a client
disconnects
from my listener, the CPU usage goes up 100% to my exe
and no connections can be made to it.
Any idea?

Not really. You didn't post a concise-but-complete code sample, so
there's no telling what in your code might be stuck in a loop.

That said, it's certainly possible that the loop you posted for some
reason turns out to be the problem. I admit, from the code you posted
it's not clear why your loop works at all (when would "byteReadStream"
ever _not_ be null?). But assuming there's some condition under which
you're not exiting the loop, it wouldn't surprise me to find that you
wind up consuming 100% CPU, because it's probably a scenario in which no
progress towards exiting the loop is made.

You shouldn't be using the Available property anyway. It's not a
reliable indicator of what you can read. But without a complete code
sample, it's not really possible to offer more detailed advice as to how
to fix your program.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top