Link to home
Start Free TrialLog in
Avatar of DaFou
DaFou

asked on

Storing stream writers

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();
                        //}
                  //}
            }
      }
}
Avatar of dukkorg
dukkorg

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.
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.
Avatar of DaFou

ASKER

I am trying to make a DHTML chat server:

I am buzy for some time on this:
https://www.experts-exchange.com/questions/21057802/How-to-collect-store-and-respond-to-incomming-requests.html

threads are ok but I first need proof of concept
Writing your own web server is probably the wrong way to go for this. You would be better off using ASP.Net.
Avatar of DaFou

ASKER

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
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.
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.
Avatar of DaFou

ASKER

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
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.
Avatar of DaFou

ASKER

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.
Avatar of DaFou

ASKER

and could you show me how to test this useing telnet?
Avatar of DaFou

ASKER

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
ASKER CERTIFIED SOLUTION
Avatar of dukkorg
dukkorg

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of DaFou

ASKER

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,
Avatar of DaFou

ASKER

Ahh yeah,

I did it :-) Now I need to introduce threads
https://www.experts-exchange.com/questions/21091010/How-to-introduce-new-threads.html

500 points again.