471,325 Members | 1,671 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,325 software developers and data experts.

Question abut threads

I am working on a program that creates a few TCP listenrs to accept data
from non .net processes.
Each listener listens in its own thread. I am using Thread.Sleep(1000) to
let other threads work.
Here is my code:
tcpl = new TcpListener(ipe);
TcpClient tcpc = tcpl.AcceptTcpClient();
while (true)
{
// get data
while (true)
{
// if contidion met break;
}
Thread.Sleep(1000) ;
}

Do I really need Thread.Sleep(1000) ? What would happend if I dont use it at
all?

Thanks
Aug 7 '08 #1
21 1341
On Aug 7, 1:25*pm, "Markgoldin" <markgoldin_2...@yahoo.comwrote:
I am working on a program that creates a few TCP listenrs to accept data
from non .net processes.
Each listener listens in its own thread. I am using Thread.Sleep(1000) to
let other threads work.
Here is my code:
tcpl = new TcpListener(ipe);
TcpClient tcpc = tcpl.AcceptTcpClient();
while (true)
{
* * // get data
* * while (true)
* * {
* * * * // if contidion met break;
* * }
* * Thread.Sleep(1000) ;

}

Do I really need Thread.Sleep(1000) ? What would happend if I dont use itat
all?
That depends on what happens in the loop. Are you actually likely to
be processor bound? Is your while loop a tight loop? If so, that's the
thing to fix.

It's unlikely that you should really be sleeping, but if you ever need
to wait for a condition to be met, you should probably be using an
Auto/ManualResetEvent or Monitor.Wait/Pulse.

Jon
Aug 7 '08 #2
On Aug 7, 8:25*am, "Markgoldin" <markgoldin_2...@yahoo.comwrote:
I am working on a program that creates a few TCP listenrs to accept data
from non .net processes.
Each listener listens in its own thread. I am using Thread.Sleep(1000) to
let other threads work.
you should only do this if each listener listen in a different post.

Here is my code:
tcpl = new TcpListener(ipe);
TcpClient tcpc = tcpl.AcceptTcpClient();
while (true)
{
* * // get data
* * while (true)
* * {
* * * * // if contidion met break;
* * }
* * Thread.Sleep(1000) ;

}

Do I really need Thread.Sleep(1000) ? What would happend if I dont use itat
all?
why you use it in the first place??

Answer to this, are you using one port or multiple ports?
I can give you code in each case, it's as simple as using a SyncQueue.
and one thread per connection (no per listener)
Aug 7 '08 #3
On Thu, 07 Aug 2008 08:04:03 -0700, Ignacio Machin ( .NET/ C# MVP )
<ig************@gmail.comwrote:
On Aug 7, 8:25Â*am, "Markgoldin" <markgoldin_2...@yahoo.comwrote:
>I am working on a program that creates a few TCP listenrs to accept data
from non .net processes.
Each listener listens in its own thread. I am using Thread.Sleep(1000)
to
let other threads work.

you should only do this if each listener listen in a different post.
I believe Ignacio has a one-letter type here: "post" should be "port".
Hopefully that was clear from the rest of his message, but if not this
should clear it up. :)
[...]
>Do I really need Thread.Sleep(1000) ? What would happend if I dont use
it at
all?

why you use it in the first place??

Answer to this, are you using one port or multiple ports?
I can give you code in each case, it's as simple as using a SyncQueue.
and one thread per connection (no per listener)
I don't find the type "SyncQueue" in the MSDN documentation, so I don't
know what Ignacio is getting at. That said, I'll suggest that there are
really only two viable approaches to TCP network i/o in .NET:

-- one thread per connection, using blocking i/o
-- asynchronous API (e.g. Socket.BeginReceive(), etc.)

(For i/o using the Socket class directly, there is a Select() method
similar to BSD sockets's select() function which is theoretically simpler
than the asynchronous API, but personally I think it's both awkward and
inefficient. .NET has much better i/o paradigms to take advantage of).

The former can be the simplest, assuming each connection is completely
independent from each other. But it's only appropriate for relatively
small numbers of remote endpoints (hundreds, at the very most). The
latter is much more scalable, and more importantly, most implementations
other than the "one thread per connection" design are going to wind up
involving some similar thread management issues anyway. One might as well
use the built-in threaded i/o rather than reinventing the wheel.

MSDN has code samples for the asynchronous API both in the Socket class
and, if I recall correctly, the TcpListener/TcpClient classes.

Pete
Aug 7 '08 #4
On Aug 7, 12:34*pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Thu, 07 Aug 2008 08:04:03 -0700, Ignacio Machin ( .NET/ C# MVP ) *

<ignacio.mac...@gmail.comwrote:
On Aug 7, 8:25*am, "Markgoldin" <markgoldin_2...@yahoo.comwrote:
I am working on a program that creates a few TCP listenrs to accept data
from non .net processes.
Each listener listens in its own thread. I am using Thread.Sleep(1000)*
to
let other threads work.
you should only do this if each listener listen in a different post.

I believe Ignacio has a one-letter type here: "post" should be "port". *
Hopefully that was clear from the rest of his message, but if not this *
should clear it up. *:)
Sorry for the mistake, I also noticed a couple of words in spanish in
another post, I've been without coffee the entire morning, not good
for health :)
I don't find the type "SyncQueue" in the MSDN documentation, so I don't *
know what Ignacio is getting at. *That said, I'll suggest that there are *
really only two viable approaches to TCP network i/o in .NET:

There is none, but you have Queue.Synchronized method:
Returns a Queue wrapper that is synchronized (thread safe).

Seet his example:
Queue connectionQueue;
protected override void OnStart(string[] args)
{
listenerThread = new Thread( new ThreadStart( ListenerMethod));
listenerThread.Start();
}
protected void ListenerMethod()

{
Thread workingthread;
Queue unsyncq = new Queue();
connectionQueue = Queue.Synchronized( unsyncq);
TcpClient socket;
TcpListener listener = new TcpListener( 1212);

listener.Start();
while( true)
{
socket = listener.AcceptTcpClient();
connectionQueue.Enqueue( socket);
workingthread = new Thread( new
ThreadStart( TheConnectionHandler));
workingthread.Start();
}
}
public void TheConnectionHandler()
{
TcpClient socket= (TcpClient)connectionQueue.Dequeue();
//use the socket
}
Aug 7 '08 #5
On Thu, 07 Aug 2008 11:18:01 -0700, Ignacio Machin ( .NET/ C# MVP )
<ig************@gmail.comwrote:
[...]
>I don't find the type "SyncQueue" in the MSDN documentation, so I don't
know what Ignacio is getting at. Â*That said, I'll suggest that there
are Â*
really only two viable approaches to TCP network i/o in .NET:

There is none, but you have Queue.Synchronized method:
Returns a Queue wrapper that is synchronized (thread safe).

Seet his example:
All due respect and no offense intended, but... yuck! :)

You're using the queue just as a way of passing data from one thread to
another? What's wrong with using ParameterizedThreadStart? For example:

protected void ListenerMethod()
{
TcpListener listener = new TcpListener(1212);

listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();

new Thread(TheConnectionHandler).Start(client);
}
}

protected void TheConnectionHandler(object objArg)
{
TcpClient client = (TcpClient)objArg;

//...
}

Notes:

-- I prefer to use the variable name "socket" only when it's actually
a Socket instance. TcpClient wraps a Socket, and can be used in similar
ways. But it's not really a Socket and thinking it is could lead to some
confusion.

-- The compiler can infer the correct type for the Thread constructor
and create the delegate for you, so you don't actually need to explicitly
specify "new ThreadStart(...)" or "new ParameterizedThreadStart(...)" when
creating the Thread instance.

A slight variation on the above theme would be to capture the "client"
variable in an anonymous method and avoid casting altogether:

protected void ListenerMethod()
{
TcpListener listener = new TcpListener(1212);

listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();

new Thread(delegate { TheConnectionHandler(client) }).Start();
}
}

protected void TheConnectionHandler(TcpClient client)
{
//...
}

I still prefer the asynchronous methods. But the above are, I think, at
least more appropriate than creating a queue just for the purpose of
moving a single reference from one thread to another.

Just my two cents.

Pete
Aug 7 '08 #6
On Thu, 07 Aug 2008 11:33:48 -0700, Peter Duniho
<Np*********@nnowslpianmk.comwrote:
[...]
new Thread(delegate { TheConnectionHandler(client)
}).Start();
Sorry...forgot a semi-colon there. I assume the reader can easily fix
that, but just in case:

new Thread(delegate { TheConnectionHandler(client); }).Start();
Aug 7 '08 #7
Instead of using threads to keep client state, you may want to look into
using async comm. The fx3.5 has some improvements in socket class that may
help:
http://msdn.microsoft.com/en-us/magazine/cc163356.aspx
--wjs

"Markgoldin" <ma*************@yahoo.comwrote in message
news:eV****************@TK2MSFTNGP06.phx.gbl...
>I am working on a program that creates a few TCP listenrs to accept data
from non .net processes.
Each listener listens in its own thread. I am using Thread.Sleep(1000) to
let other threads work.
Here is my code:
tcpl = new TcpListener(ipe);
TcpClient tcpc = tcpl.AcceptTcpClient();
while (true)
{
// get data
while (true)
{
....

Aug 8 '08 #8
On Aug 7, 2:33*pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Thu, 07 Aug 2008 11:18:01 -0700, Ignacio Machin ( .NET/ C# MVP ) *

<ignacio.mac...@gmail.comwrote:
[...]
I don't find the type "SyncQueue" in the MSDN documentation, so I don't *
know what Ignacio is getting at. *That said, I'll suggest that there*
are *
really only two viable approaches to TCP network i/o in .NET:
There is none, but you have Queue.Synchronized *method:
Returns a Queue wrapper that is synchronized (thread safe).
Seet his example:

All due respect and no offense intended, but... *yuck! *:)

You're using the queue just as a way of passing data from one thread to *
another? *What's wrong with using ParameterizedThreadStart? *For example:
No offense taken :)

You are right, you can use ParameterizedThreadStart . The thing is
that that piece of code is from 1.1 era , you had no
ParameterizedThreadStart back then :)
This is the original post:

http://groups.google.com/group/micro...eabe586c0924e0

Just recently I updated it to 2005 but the code is the same, it works,
so why change it ? :)
* * *protected void ListenerMethod()
* * *{
* * * * *TcpListener listener = new TcpListener(1212);

* * * * *listener.Start();
* * * * *while (true)
* * * * *{
* * * * * * *TcpClient client = listener.AcceptTcpClient();

* * * * * * *new Thread(delegate { TheConnectionHandler(client) }).Start();
* * * * *}
* * *}

* * *protected void TheConnectionHandler(TcpClient client)
* * *{
* * * * *//...
* * *}
That would be the best solution :)
Aug 8 '08 #9
On Fri, 08 Aug 2008 08:03:54 -0700, Ignacio Machin ( .NET/ C# MVP )
<ig************@gmail.comwrote:
[...]
Just recently I updated it to 2005 but the code is the same, it works,
so why change it ? :)
For your own use? I see no reason to change it. For the purpose of
providing suggestions to others? I'm sure you can figure out what _I_
think... :)

For what it's worth, even in 1.1 I think there are better approaches. For
example:

class MainClass
{
// Since in 1.1 we wouldn't have this delegate type, define
// it ourselves.
delegate void ParameterizedThreadStart(object objParameter);

class ThreadWithParameter
{
ParameterizedThreadStart _start;
object _objParameter;

public ThreadWithParameter(ParameterizedThreadStart start,
object objParameter)
{
_start = start;
_objParameter = objParameter;
}

public void StartMethod()
{
_start(_objParameter);
}
}

void MethodThatStartsThread()
{
object objParameter = new object(); // or whatever you want
ThreadWithParameter twp =
new ThreadWithParameter(
new ParameterizedThreadStart(DesiredThreadStart),
objParameter);

new Thread(new ThreadStart(twp.StartMethod)).Start();
}

void DesiredThreadStart(object objParameter)
{
// do some work in a thread
}
}

(The "ThreadWithParameter" class doesn't actually need to be nested as
above. Though, if you want to tie the class more closely to whatever code
is actually running the thread, that could make it more convenient).

To me, using a synchronized Queue makes a lot of sense if you're starting
multiple threads with the same entry point but each with different input.
But otherwise, it seems like overkill at best, and maybe a bit confusing
and misleading at worst. It's not _terrible_ in any case, but it does
seem awkward and not very expressive. :)

Pete
Aug 8 '08 #10
On Aug 8, 12:35*pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Fri, 08 Aug 2008 08:03:54 -0700, Ignacio Machin ( .NET/ C# MVP ) *

<ignacio.mac...@gmail.comwrote:
[...]
Just recently I updated it to 2005 but the code is the same, it works,
so why change it ? :)

For your own use? *I see no reason to change it. *For the purpose of *
providing suggestions to others? *I'm sure you can figure out what _I_ *
think... *:)
yes, you are right, my bad :)
I do not know why but this is a frequent request, so all I do is a
search in google and I always find my old post with the old code.
Thank to you now this thread will be returned from now on.

To me, using a synchronized Queue makes a lot of sense if you're starting*
multiple threads with the same entry point but each with different input.*
But otherwise, it seems like overkill at best, and maybe a bit confusing *
and misleading at worst. *It's not _terrible_ in any case, but it does *
seem awkward and not very expressive. *:)

Pete
IMHO the solution with the queue seems clearer than the use of a
nested class to hold the parameter. You have to write much less code
and can be extended very easily for example when you need to change
the delegate at runtime.
Aug 8 '08 #11
On Fri, 08 Aug 2008 13:26:13 -0700, Ignacio Machin ( .NET/ C# MVP )
<ig************@gmail.comwrote:
[...]
IMHO the solution with the queue seems clearer than the use of a
nested class to hold the parameter. You have to write much less code
and can be extended very easily for example when you need to change
the delegate at runtime.
Okay, let's be sure to emphasize: this is _only_ in the context of .NET
1.1 anyway. C#/.NET 2.0 and later includes the better
ParameterizedThreadStart.

As far as the queue vs. nest class goes, I agree there's less code for the
Queue. But IMHO it's a misleading use of the data structure. Queues are
always about putting data in one end, and taking it out at the other.
When one uses a queue, it implies that you've got this sort of pipeline
going on. Using it as a temporary cubby-hole causes an implication to
exist in the code that isn't necessarily true.

Now, to be clear: there are in fact cases where a queue makes sense for
this very type of thing. In particular, as I mentioned, if you are
creating multiple threads that all do the same processing, then in fact
using the queue as part of a traditional producer/consumer sort of design
makes a lot of sense.

But it's my opinion that when that's not really what's going on, using a
queue can easily cause someone else reading the code to be misled about
the true design of the code. In that case, writing a few more lines of
code so that the actual design is more explicitly represented by the code
without any misleading cues is well worth the trade-off.

YMMV...if you remain unconvinced, that's fine. Some people do prefer
concise code over all other priorities. I just want to make sure my point
of view has been clearly expressed. :)

Pete
Aug 8 '08 #12
Yes, each listener listen to a different port.
I am using 8 ports for now.

Here is my code, one for each port:
goJM4 = true;

// Buffer for reading data

Byte[] bytes = new Byte[1024];

TcpClient tcpc = DataAdapterLauncher.tcplJM4.AcceptTcpClient(); //accept
connection

String data;

while (goJM4)

{

data = "";

// Get a stream object for reading and writing

NetworkStream stream = tcpc.GetStream();

// Loop to receive all the data sent by the client.

int i = 0;

i = stream.Read(bytes, 0, bytes.Length);

while (i 0)

{

i = stream.Read(bytes, 0, bytes.Length);

// Translate data bytes to a ASCII string.

data += System.Text.Encoding.ASCII.GetString(bytes, 0, i);

if (data.EndsWith("\r") || i == 0)

break;

}

// Process the data sent by the client.

if (data != "")

{

System.Console.WriteLine(data);

}

}
What is also happening that almost constantly I am not getting all data
being sent.
I am writing into SQL a record every time I am sending data and I dont have
anything missed but
in the Console the data shown is not everything I am sending. The one that
has been shown is complete
but not all messages are shown.
Any idea how to trouble shoot that?

Thanks

"Ignacio Machin ( .NET/ C# MVP )" <ig************@gmail.comwrote in
message
news:31**********************************@m3g2000h sc.googlegroups.com...
On Aug 7, 8:25 am, "Markgoldin" <markgoldin_2...@yahoo.comwrote:
I am working on a program that creates a few TCP listenrs to accept data
from non .net processes.
Each listener listens in its own thread. I am using Thread.Sleep(1000) to
let other threads work.
you should only do this if each listener listen in a different post.

Here is my code:
tcpl = new TcpListener(ipe);
TcpClient tcpc = tcpl.AcceptTcpClient();
while (true)
{
// get data
while (true)
{
// if contidion met break;
}
Thread.Sleep(1000) ;

}

Do I really need Thread.Sleep(1000) ? What would happend if I dont use it
at
all?
why you use it in the first place??

Answer to this, are you using one port or multiple ports?
I can give you code in each case, it's as simple as using a SyncQueue.
and one thread per connection (no per listener)
Aug 8 '08 #13
In your code sample:
protected void ListenerMethod()
{
TcpListener listener = new TcpListener(1212);

listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();

new Thread(TheConnectionHandler).Start(client);
}
}
Why do you have TcpClient client = listener.AcceptTcpClient();
inside of the loop?
If to accept connections from differnt clients then does a client have to
disconnect every time after the data has been sent?

Thanks

"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Thu, 07 Aug 2008 11:18:01 -0700, Ignacio Machin ( .NET/ C# MVP )
<ig************@gmail.comwrote:
>[...]
>>I don't find the type "SyncQueue" in the MSDN documentation, so I don't
know what Ignacio is getting at. That said, I'll suggest that there are
really only two viable approaches to TCP network i/o in .NET:

There is none, but you have Queue.Synchronized method:
Returns a Queue wrapper that is synchronized (thread safe).

Seet his example:

All due respect and no offense intended, but... yuck! :)

You're using the queue just as a way of passing data from one thread to
another? What's wrong with using ParameterizedThreadStart? For example:

protected void ListenerMethod()
{
TcpListener listener = new TcpListener(1212);

listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();

new Thread(TheConnectionHandler).Start(client);
}
}

protected void TheConnectionHandler(object objArg)
{
TcpClient client = (TcpClient)objArg;

//...
}

Notes:

-- I prefer to use the variable name "socket" only when it's actually
a Socket instance. TcpClient wraps a Socket, and can be used in similar
ways. But it's not really a Socket and thinking it is could lead to some
confusion.

-- The compiler can infer the correct type for the Thread constructor
and create the delegate for you, so you don't actually need to explicitly
specify "new ThreadStart(...)" or "new ParameterizedThreadStart(...)" when
creating the Thread instance.

A slight variation on the above theme would be to capture the "client"
variable in an anonymous method and avoid casting altogether:

protected void ListenerMethod()
{
TcpListener listener = new TcpListener(1212);

listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();

new Thread(delegate { TheConnectionHandler(client) }).Start();
}
}

protected void TheConnectionHandler(TcpClient client)
{
//...
}

I still prefer the asynchronous methods. But the above are, I think, at
least more appropriate than creating a queue just for the purpose of
moving a single reference from one thread to another.

Just my two cents.

Pete

Aug 8 '08 #14
On Fri, 08 Aug 2008 14:26:38 -0700, Markgoldin <ma*************@yahoo.com>
wrote:
In your code sample:
protected void ListenerMethod()
{
TcpListener listener = new TcpListener(1212);

listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();

new Thread(TheConnectionHandler).Start(client);
}
}
Why do you have TcpClient client = listener.AcceptTcpClient();
inside of the loop?
Because there's no need to have it outside the loop.
If to accept connections from differnt clients then does a client have to
disconnect every time after the data has been sent?
It depends on how the server is designed. But, in the example I gave, the
code is dedicating a new thread to each connection. So there is no need
to disconnect an existing client just to accept a new connection from
another client.

You didn't provide enough details in your original post to know whether
that's consistent with your design. Whether it is or not though, there's
still no reason to put the TcpClient declaration outside the listening
loop.

Pete
Aug 8 '08 #15
On Fri, 08 Aug 2008 14:19:23 -0700, markgoldin <ma*************@yahoo.com>
wrote:
Yes, each listener listen to a different port.
I am using 8 ports for now.
Any particular reason why? One port should be sufficient, assuming the
rest of your code is designed correctly.

For sure, you've got at least one serious bug:
[...]
i = stream.Read(bytes, 0, bytes.Length);

while (i 0)

{

i = stream.Read(bytes, 0, bytes.Length);
Whatever bytes you read from the stream in your first call to Read(), you
simply discard. I'm surprised that you get _any_ successful results with
this code. Maybe you have some bug elsewhere that somehow offsets this
bug.

And here's a line of code that could be bug if it was extrapolated to
other encodings:
// Translate data bytes to a ASCII string.

data += System.Text.Encoding.ASCII.GetString(bytes, 0, i);
I'd have to spend a little more time reviewing the Encoding class stuff,
but my recollection is that you need to get a single Encoding instance and
use it repeatedly when decoding strings from a byte stream. Otherwise, if
you receive partial data, it will get lost between calls to GetString().

Since ASCII is always only one byte per character, this isn't a problem
with ASCII per se. But if you were to change your design to transmit
encodings it would be.

But for now, the main thing you need to fix is to stop discarding the
first sequence of bytes you receive. As a minimal change to your code,
I'd suggest something like this:

i = stream.Read(bytes, 0, bytes.Length);

while (i 0 && !data.EndsWith("\r"))
{
// Translate data bytes to a ASCII string.

data += System.Text.Encoding.ASCII.GetString(bytes, 0, i);

i = stream.Read(bytes, 0, bytes.Length);
}

You may also want to consider changing your code so that it uses a
StringBuilder to accumulate the string, rather than repeatedly
accumulating the string being read in. Whether it's really a problem
depends on how many times you're actually doing to concatenate and how
long the string will eventually get. But for large strings, StringBuilder
will be much more efficient.

Pete
Aug 8 '08 #16
Pete, thanks a lot for fixing my code. Really appreciate that.

I dont have any particular reason for 8 ports except that I have 8 clients
sending data to the .Net module.

These clients are scanner (data collection) servers. Users scan barcodes
which are going into different from .Net processes.

Then these processes send data to .Net module via sockets.

Creating separate ports for each scanning process should protect me from
concurrency problems when multiple users are scanning at the same time.

I have queuing mechanism on the data side too: I am trying not to send data
from multiple users at the same time, but for the sake of stability of the
program

I am also dedicating a port to each data stream.

protected void ListenerMethod()
{
TcpListener listener = new TcpListener(1212);
listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();
new Thread(delegate { TheConnectionHandler(client); }).Start();
//new Thread(TheConnectionHandler).Start(client);
}
}

protected void TheConnectionHandler(object objArg)
{
TcpClient client = (TcpClient)objArg;

//...
}

I have a few questions about your code. How does exactly it work? Does it
create a new thread every time data has been sent?

Also where in the code do I extract data?

About having TcpClient client = listener.AcceptTcpClient(); inside of the
loop. I tried (before getting samples here) to have it inside, but

I wasn't eble to receive data more than once so I took it out of the loop.

Thanks again for all the help.
"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Fri, 08 Aug 2008 14:19:23 -0700, markgoldin <ma*************@yahoo.com>
wrote:
>Yes, each listener listen to a different port.
I am using 8 ports for now.

Any particular reason why? One port should be sufficient, assuming the
rest of your code is designed correctly.

For sure, you've got at least one serious bug:
>[...]
i = stream.Read(bytes, 0, bytes.Length);

while (i 0)

{

i = stream.Read(bytes, 0, bytes.Length);

Whatever bytes you read from the stream in your first call to Read(), you
simply discard. I'm surprised that you get _any_ successful results with
this code. Maybe you have some bug elsewhere that somehow offsets this
bug.

And here's a line of code that could be bug if it was extrapolated to
other encodings:
>// Translate data bytes to a ASCII string.

data += System.Text.Encoding.ASCII.GetString(bytes, 0, i);

I'd have to spend a little more time reviewing the Encoding class stuff,
but my recollection is that you need to get a single Encoding instance and
use it repeatedly when decoding strings from a byte stream. Otherwise, if
you receive partial data, it will get lost between calls to GetString().

Since ASCII is always only one byte per character, this isn't a problem
with ASCII per se. But if you were to change your design to transmit
encodings it would be.

But for now, the main thing you need to fix is to stop discarding the
first sequence of bytes you receive. As a minimal change to your code,
I'd suggest something like this:

i = stream.Read(bytes, 0, bytes.Length);

while (i 0 && !data.EndsWith("\r"))
{
// Translate data bytes to a ASCII string.

data += System.Text.Encoding.ASCII.GetString(bytes, 0, i);

i = stream.Read(bytes, 0, bytes.Length);
}

You may also want to consider changing your code so that it uses a
StringBuilder to accumulate the string, rather than repeatedly
accumulating the string being read in. Whether it's really a problem
depends on how many times you're actually doing to concatenate and how
long the string will eventually get. But for large strings, StringBuilder
will be much more efficient.

Pete

Aug 9 '08 #17
On Sat, 09 Aug 2008 03:34:43 -0700, User Groups
<ma*************@yahoo.comwrote:
[...]
Creating separate ports for each scanning process should protect me from
concurrency problems when multiple users are scanning at the same time.
No, not really. The TcpListener class internally addresses any
concurrency issue with respect to simultaneous, multiple connection
requests. And any other concurrency issue that might exist when using the
same port will exist when using different ports.

Multiple ports is not a valid solution to concurrency issues.
I have queuing mechanism on the data side too: I am trying not to send
data
from multiple users at the same time, but for the sake of stability of
the
program

I am also dedicating a port to each data stream.
I wouldn't worry about trying to synchronize on the client side. Your
server can and should be designed to handle multiple concurrent clients,
and then you can avoid any additional complexity on the client side.
[...]
I have a few questions about your code. How does exactly it work? Does it
create a new thread every time data has been sent?
Yes. This is a common technique for dealing with multiple connections,
where the number of connections will be small.
Also where in the code do I extract data?
Your code to read from a TcpClient would be put in the
"TheConnectionHandler()" method.
About having TcpClient client = listener.AcceptTcpClient(); inside of the
loop. I tried (before getting samples here) to have it inside, but

I wasn't eble to receive data more than once so I took it out of the
loop.
It depends on what you mean by "the loop". In the code I posted, "the
loop" _only_ deals with accepting connections. Perhaps in your own code
you also tried to read from the connection in the same method (not a great
design, but doable). But even there, the loop to read data should have
been nested within the loop that accepts connections, and
declaring/initializing the TcpClient variable within the outer loop should
have been fine.

Without seeing the full code, there's nothing more I could comment on with
respect to that.

Pete
Aug 9 '08 #18
I am implemeting your code and I am getitng the following error:
Error 2 The call is ambiguous between the following methods or properties:
'System.Threading.Thread.Thread(System.Threading.T hreadStart)' and
'System.Threading.Thread.Thread(System.Threading.P arameterizedThreadStart)'
at this line:
new Thread(delegate { ConnectionHandler(tcpc); }).Start();

Can you help?


"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Fri, 08 Aug 2008 14:26:38 -0700, Markgoldin <ma*************@yahoo.com>
wrote:
>In your code sample:
protected void ListenerMethod()
{
TcpListener listener = new TcpListener(1212);

listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();

new Thread(TheConnectionHandler).Start(client);
}
}
Why do you have TcpClient client = listener.AcceptTcpClient();
inside of the loop?

Because there's no need to have it outside the loop.
>If to accept connections from differnt clients then does a client have to
disconnect every time after the data has been sent?

It depends on how the server is designed. But, in the example I gave, the
code is dedicating a new thread to each connection. So there is no need
to disconnect an existing client just to accept a new connection from
another client.

You didn't provide enough details in your original post to know whether
that's consistent with your design. Whether it is or not though, there's
still no reason to put the TcpClient declaration outside the listening
loop.

Pete

Aug 11 '08 #19
On Aug 11, 2:51*pm, "Markgoldin" <markgoldin_2...@yahoo.comwrote:
I am implemeting your code and I am getitng the following error:
Error 2 The call is ambiguous between the following methods or properties:
'System.Threading.Thread.Thread(System.Threading.T hreadStart)' and
'System.Threading.Thread.Thread(System.Threading.P arameterizedThreadStart)'
at this line:
new Thread(delegate { ConnectionHandler(tcpc); }).Start();

Can you help?
That's using the form of anonymous method construction which doesn't
specify the parameters. You want to specify that you don't need any
parameters, so use:
delegate() { ConnectionHandler(tcpc); }

The () after delegate is the important bit.

Jon
Aug 11 '08 #20
Here is my code after I applied everything I have gathered here:

public void Run()

{

go = true;

while (go)

{

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

new Thread(delegate() { ConnectionHandler(tcpc); }).Start();

}

}

protected void ConnectionHandler(object objArg)

{

TcpClient client = (TcpClient)objArg;

// Buffer for reading data

Byte[] bytes = new Byte[1024];

String data;

data = "";

// Get a stream object for reading and writing

NetworkStream stream = client.GetStream();

// Loop to receive all the data sent by the client.

int i = 0;

i = stream.Read(bytes, 0, bytes.Length);

while (i 0 && !data.EndsWith("\r"))

{

// Translate data bytes to a ASCII string.

data += System.Text.Encoding.ASCII.GetString(bytes, 0, i);

i = stream.Read(bytes, 0, bytes.Length);

}

// Process the data sent by the client.

if (data != "")

{

System.Console.WriteLine(data);

IDictionary eventData = new Hashtable();

eventData["scan"] = data;

_listener.Update("floorupdate", eventData, false);

}

}

DataAdapterLauncher.tcpl starts in another class:

IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 63335);//listen
on all local addresses
tcpl = new TcpListener(ipe);

tcpl.Start();

As I was saying it only accepts data once.

I am checking my client side and I see that data is getitng sent but
while (go)

{

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

new Thread(delegate() { ConnectionHandler(tcpc); }).Start();

}

with
System.Console.WriteLine(1); in it

shows 1 only once.

Any idea?

"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Fri, 08 Aug 2008 14:26:38 -0700, Markgoldin <ma*************@yahoo.com>
wrote:
>In your code sample:
protected void ListenerMethod()
{
TcpListener listener = new TcpListener(1212);

listener.Start();
while (true)
{
TcpClient client = listener.AcceptTcpClient();

new Thread(TheConnectionHandler).Start(client);
}
}
Why do you have TcpClient client = listener.AcceptTcpClient();
inside of the loop?

Because there's no need to have it outside the loop.
>If to accept connections from differnt clients then does a client have to
disconnect every time after the data has been sent?

It depends on how the server is designed. But, in the example I gave, the
code is dedicating a new thread to each connection. So there is no need
to disconnect an existing client just to accept a new connection from
another client.

You didn't provide enough details in your original post to know whether
that's consistent with your design. Whether it is or not though, there's
still no reason to put the TcpClient declaration outside the listening
loop.

Pete

Aug 11 '08 #21
On Mon, 11 Aug 2008 10:19:01 -0700, Markgoldin <ma*************@yahoo.com>
wrote:
[...]
I am checking my client side and I see that data is getitng sent but
while (go)

{

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

new Thread(delegate() { ConnectionHandler(tcpc); }).Start();

}

with
System.Console.WriteLine(1); in it

shows 1 only once.

Any idea?
Well, how many times do you try to connect to the listener?

AcceptTcpClient() is only going to return once for every time some remote
endpoint tries to actually connect.

You didn't post the client code, but given that AcceptTcpClient() only
appears to be returning a new connection once, the client is probably only
trying to connect once.

For what it's worth, your code samples so far have been very hard to read,
because they lack any indentation. For future posts, it would be very
helpful if you would make sure that your code has some indentation (three
or four spaces per block level would be nice). And ideally, you would
post a concise-but-complete sample...that is, your code should be
self-contained, compilable without error and reliably demonstrate the
issue. For networking issues, that means you need to post code for both
ends, client and server.

Pete
Aug 11 '08 #22

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Dean Speir | last post: by
2 posts views Thread by grahamo | last post: by
5 posts views Thread by Timur | last post: by
1 post views Thread by serge calderara | last post: by
4 posts views Thread by Rui Maciel | last post: by
9 posts views Thread by Gilbert | last post: by
3 posts views Thread by Chris Roth | last post: by
19 posts views Thread by frankiespark | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.