Solved

Storing stream writers

Posted on 2004-07-31
16
530 Views
Last Modified: 2008-02-01
Ola,

I want to collect streamwriters that write to tcp clients. The code will work like it is made for only 1 client. But when we uncomment the two for loops ( that sould enable the storing of 2 clients ) the client all of a sudden does not receive the response anymore.
Why is that?

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections;
using System.IO;

namespace AtomHTTPresponse
{
      class AtomHTTPresponse
      {
            private ArrayList lObjArrayList = new ArrayList();
            static void Main(string[] args)
            {
                  AtomHTTPresponse lObjAtomHTTPresponse = new AtomHTTPresponse();
                  TcpListener lObjTcpListner = new TcpListener( 9999 );
                  lObjTcpListner.Start();
                  
                  int lCntOuter = 0;
                  //for ( int lCntOuter = 0; lCntOuter < 3; lCntOuter++ )
                  //{
                        Console.WriteLine( "Listening for client " + lCntOuter );
                        TcpClient lObjTcpClient = lObjTcpListner.AcceptTcpClient();
                        Console.WriteLine( "Got client " + lCntOuter );
                        NetworkStream lObjNetworkStream = lObjTcpClient.GetStream();
                        
                        StreamReader reader = new StreamReader( lObjNetworkStream );
                        StreamWriter writer = new StreamWriter( lObjNetworkStream );
                        while (reader.Peek() >= 0)
                        {
                              char[] c = new char[256];
                              reader.Read(c, 0, c.Length);
                              //Console.Write(c);
                              // I am reading the stream but not writing to make sure I am sending the response after the request is done
                        }
                        lObjAtomHTTPresponse.lObjArrayList.Add( writer );
                        
                        int lCntInner = 0;
                        //for ( int lCntInner = 0; lCntInner < lObjAtomHTTPresponse.lObjArrayList.Count; lCntInner++ )
                        //{
                              Console.WriteLine( "Writing to client " + lCntInner );
                              StreamWriter writer2 = ( StreamWriter ) lObjAtomHTTPresponse.lObjArrayList[ lCntInner ];
                              writer2.Write( lCntInner + " clients connected" );
                              writer2.Flush();
                        //}
                  //}
            }
      }
}
0
Comment
Question by:DaFou
  • 9
  • 7
16 Comments
 
LVL 3

Expert Comment

by:dukkorg
Comment Utility
What exactly are you trying to accomplish here? Are you trying to do a chat server? I could probably help you better if I knew where you where going with all of this.
0
 
LVL 3

Expert Comment

by:dukkorg
Comment Utility
Also if you want to have more than one client connect and have them be able to send data back and forth to each other you’re going to have a very hard time without using threads. I would highly suggest using them.
0
 
LVL 2

Author Comment

by:DaFou
Comment Utility
I am trying to make a DHTML chat server:

I am buzy for some time on this:
http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_21057802.html

threads are ok but I first need proof of concept
0
 
LVL 2

Author Comment

by:DaFou
Comment Utility
Here I explain what I want to do actually:
http://www.experts-exchange.com/Web/Web_Servers/IIS/Q_20924430.html
0
 
LVL 3

Expert Comment

by:dukkorg
Comment Utility
Writing your own web server is probably the wrong way to go for this. You would be better off using ASP.Net.
0
 
LVL 2

Author Comment

by:DaFou
Comment Utility
No, it will be extremly hard to impossible to do it in ASP.NET.
And further more I dont wat to write my own webserver. I simply need this concept to work and I am in the clear.
My DHTML chatserver will act much different then a webserver.

Please work with me on this if you have time. Ill take things step by step question by question to reflect the effort to several times 500 points. FOr now I'd like to know why i cant loop the code but I can do it once.

Regards
0
 
LVL 3

Expert Comment

by:dukkorg
Comment Utility
Here's a demo I did years ago that showed how to update a web page without refreshing the page (only in ie) that uses ASP.Net and XML Data Islands.:

http://www.dukk.org/demos/XmlDataIslandsPageUpdate/default.htm

This demo is only updating the time but there is nothing stopping it from being able to update a table full of chat message.

That would probably work better for what your trying to do. This way you have a someone on your web page that just posts using a form in another frame and it would tell the server to update this XML file. Then each client would get a new XML file with everyone's chat message's in it.
0
 
LVL 3

Expert Comment

by:dukkorg
Comment Utility
for web browsers that don't support XML Data Islands you could have the server generate flat HTMLfile with all the message's that tell the browser not to cache them and just have javascript refresh the page.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 2

Author Comment

by:DaFou
Comment Utility
Thank you Dukkorg for your suggestions.
I am fairly experianced in some other methods then the one i propose to make a chat application but this method I propose has been in my mind for a long time now and I jsut want to see it work.
So although other methods might work aswell or even better I really want to continue with my plan.
If all else fails I have bought books on c# and books on C# network programming and I will start reading them when they arive next week.
But I really hope experts exchange can help me figure my problems out before that time.

Regards
0
 
LVL 3

Expert Comment

by:dukkorg
Comment Utility
This code works just fine:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections;
using System.IO;

namespace AtomHTTPresponse
{
      class AtomHTTPresponse
      {
            private ArrayList lObjArrayList = new ArrayList();
            static void Main(string[] args)
            {
                  AtomHTTPresponse lObjAtomHTTPresponse = new AtomHTTPresponse();
                  TcpListener lObjTcpListner = new TcpListener( 9999 );
                  lObjTcpListner.Start();
               
                  for ( int lCntOuter = 0; lCntOuter < 3; lCntOuter++ )
                  {
                        Console.WriteLine( "Listening for client " + lCntOuter );
                        TcpClient lObjTcpClient = lObjTcpListner.AcceptTcpClient();
                        Console.WriteLine( "Got client " + lCntOuter );
                        NetworkStream lObjNetworkStream = lObjTcpClient.GetStream();
                          
                        StreamReader reader = new StreamReader( lObjNetworkStream );
                        StreamWriter writer = new StreamWriter( lObjNetworkStream );
                        while (reader.Peek() >= 0)
                        {
                              char[] c = new char[256];
                              reader.Read(c, 0, c.Length);
                              //Console.Write(c);
                        }
                        lObjAtomHTTPresponse.lObjArrayList.Add( writer );
                          
                        for ( int lCntInner = 0; lCntInner < lObjAtomHTTPresponse.lObjArrayList.Count; lCntInner++ )
                        {
                              Console.WriteLine( "Writing to client " + lCntInner );
                              StreamWriter writer2 = ( StreamWriter ) lObjAtomHTTPresponse.lObjArrayList[ lCntInner ];
                              writer2.Write( lObjAtomHTTPresponse.lObjArrayList.Count + " clients connected" );
                              writer2.Flush();
                        }
                  }
            }
      }
}

You just have to open a new web browser of telnet window for each client. I ran the above code and this was my response:

Listing for client 0
Got client 0
Writing to client 0
Listing for client 1
Got client 1
Writing to client 0
Writing to client 1
Listing for client 2
Got client 2
Writing to client 0
Writing to client 1
Writing to client 2

And each browser had the proper responses. One reason you may have been having issues is if you didn't start a new browser for each request. It will blow up if you refresh the page before you get all 3 clients loaded because the browser will close the socket and cause the writes to fail.
0
 
LVL 2

Author Comment

by:DaFou
Comment Utility
and do the web browsers display the text send to them like the code would have them do at your end?
At my end the the browser displays the text with the loops commented. But shows an error when I uncomment the for loops.

And yes I use 3 different IE 6.0 browsers

Regards.
0
 
LVL 2

Author Comment

by:DaFou
Comment Utility
and could you show me how to test this useing telnet?
0
 
LVL 2

Author Comment

by:DaFou
Comment Utility
I found out that sometimes it works in where I connect to the server using
http://localhost:9999 in my IE 6.0 webbrowser and then it displays
0 clients connected

Then with another browser i connect to the server again using http://localhost:9999
That browser freezes and its display does not change.

On the first client however it now displays
0 clients connected0 clients connected
And that is a very good sign!!!!!!! kind of proof I can store the stream/connection and keep it open and write to it at a later time.

now when I stop the server client 1 is unchanged which is good but client 2 displays an error:
The page cannot be displayed


OR what can happen when the first client connects to the server is that is does act like the second client in the first situation described above



Why does it vary like this the behaviour?

Regards
0
 
LVL 3

Accepted Solution

by:
dukkorg earned 500 total points
Comment Utility
My browsers showed text in them only after all 3 browsers loaded up.  This is probably because IE is expecting HTTP headers and not text and HTTP is also a disconnected protocol so if you continue to hold connections open like this IE will probably just kill them and return a request time out. This is also the same thing that's causing your second client to display an error. Simply put the HTTP protocol wasn't designed to do this so clients for the HTTP protocol such as IE will probably give you un-expected and maybe even random results.

To tests this using telnet on windows 2000/xp/2003 you can just open a command window by going to: start -> run -> and type "cmd" then you can type "telnet localhost 9999" to create a telnet session. For this code to work you'll need to press any key before it will respond with anything.

As fare as storing the NetworkStream and the StreamWriter/StreamReaders you'll probably want to make another object that's only job in life is to keep the TcpClient, NetworkStream, the StreamReader, and the StreamWriter all in one place. And then you could store that object in a ArrayList or Hashtable so you can easily keep all your connection separated.

Something like this:

public class ConnectionObjects
{
      public TcpClient TcpClient;
      public NetworkStream Stream;
      public StreamReader Reader;
      public StreamWriter Writer;

      public ConnectionObjects(TcpClient tcpClient)
      {
            this.TcpClient = tcpClient;
            this.Stream = tcpClient.GetStream();
            this.Reader = new StreamReader(this.Stream);
            this.Writer = new StreamWriter(this.Stream);
      }
}

This way you would have a central point to clean up a connection. Just a suggestion though...
0
 
LVL 2

Author Comment

by:DaFou
Comment Utility
quote:
 "Simply put the HTTP protocol wasn't designed to do this so clients for the HTTP protocol such as IE will probably give you un-expected and maybe even random results."

Just because the HTTP protocol ( and web browsers ) was not designed to do this is the reason I want to pull it off.
I have a proof of concept as far as keeping the connection open/alive and having IE handle the responses as they come every 5 seconds. It works like a charm and ofcourse IIS sends a HTTP header before it sends anything else. That will be my next step to add an HTTP header. Ill let you know how I progress in this question


Here is the code I used in clasic ASP:

<%@ Language=VBScript %>
<%
Server.ScriptTimeout = 15 ' Letting the script run for 15 seconds is good for packet capture. I also tested 3600 and even longer using another way.
Response.Buffer = False

Dim cpBolCanRespond
cpBolCanRespond = True
While ( True )
     If ( Round( Timer() ) Mod 5 ) = 0 Then
          If cpBolCanRespond Then
               Response.Write "<script language=""javascript"">window.status = " & Round( Timer() ) & "</script>"
               cpBolCanRespond = False
          End If
     Else
          cpBolCanRespond = True
     End If
Wend
%>

Regards,
0
 
LVL 2

Author Comment

by:DaFou
Comment Utility
Ahh yeah,

I did it :-) Now I need to introduce threads
http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_21091010.html

500 points again.
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Extention Methods in C# 3.0 by Ivo Stoykov C# 3.0 offers extension methods. They allow extending existing classes without changing the class's source code or relying on inheritance. These are static methods invoked as instance method. This…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now