none
C# Server is not responding to browser request until I close the Server RRS feed

  • Question

  • Hello,

    I have created a C# Server using Socket class. My goal of this Server is to process requests from the two types of clients.

    1. A Console application

    2. Web browser

    Requests from Console application are processed correctly.

    But when request is sent from browser, browser does not display data until I close the Server application manually.

    I feel that issue exist in my code and not in browser. I am putting my code here:

    Here is my Server class:

    using System;
    using System.Collections.Generic;
    using ServerData;
    using System.Net.Sockets;
    using System.Threading;
    using System.Net;
    using Reqtify;
    using System.Timers;
    using System.Collections;
    using System.IO;
    
    namespace Server
    {
        class Server
        {
            static Socket listenerSocket;
            public static List<ClientData> clients;
            public static int portNO = 0;
            static void Main(string[] args)
            {            
                listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                clients = new List<ClientData>();
    
                //Create IP end point
                portNO = DataHelper.getExternalServerPortNo();
                IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(Packet.GetIp4Addresses()), portNO);
    
    
                //Bind the server socket to machine address
                listenerSocket.Bind(ipe);
    
                //Create listen thread and start
                Thread listenThread = new Thread(ListenThread);
                listenThread.Start();
    
                Console.WriteLine("Server :" + Packet.GetIp4Addresses()+" is started on "+ portNO);
            }
    
            //Listener that listens every client connection
    
            static void ListenThread()
            {
                for (;;)
                {
                    //Listen to client socket that is trying to connect to this Server
                    listenerSocket.Listen(0);
                    //Add connected client to list of Clients for broadcasting purpose
    
                    Socket clientSocket = listenerSocket.Accept();
                    if (!DataHelper.isSessionValid(clientSocket))
                    {
                        clients.Add(new ClientData(clientSocket));
                    }
                    else
                    {
                        //Start a new thread fo existing client
                        foreach (ClientData c in clients)
                        {
                            string clientSessionId = DataHelper.getClientSessionId(clientSocket);
    
                            if(c.sessionId == clientSessionId)
                            {
                                c.clientSocket = clientSocket;
                                Thread thread = new Thread(Server.Data_IN);
                                thread.Start(c);
                            }
                        }
                    }
                }
            }
    
            //Run the client thead which handles every client individually
            public static void Data_IN(object obj)
            {            
                ClientData clientData = (ClientData)obj;
    
                byte[] Buffer;
                int readByteSize;
    
                for (;;)
                {
                    try
                    {
                        Buffer = new byte[clientData.clientSocket.SendBufferSize];
                        readByteSize = clientData.clientSocket.Receive(Buffer);
                        char[] chars = new char[readByteSize];                    
    
                        if (readByteSize > 0)
                        {                        
                            //Reset the client timer
                            clientData.timer.Stop();
                            clientData.timer.Start();
    
                            System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
                            int charLen = d.GetChars(Buffer, 0, readByteSize, chars, 0);
                            string inputFromClient = new string(chars);   
                            string[] inputs = inputFromClient.Split(new[] {"http:"}, StringSplitOptions.None);
    
                            if(inputs.Length > 1)
                            {
                                foreach(string str in inputs)
                                {
                                    if(!str.Equals("")) {                                       
                                        //Manage request from console client
                                        DataManager("http:" + str, clientData);                                                                                                                                                                                                                                                                             
                                    }                                    
                                }
                            } else
                            {
                                //Check if request is from browser
                                if(inputFromClient.Contains("User-Agent"))
                                {
                                    //Manage http request from browser
                                    HttpProcessor hp = new HttpProcessor(clientData.clientSocket);
                                    hp.processClientInput();                                
                                }
                                else
                                {
                                    //Manage request from console client
                                    DataManager(inputFromClient, clientData);                               
                                }                            
                            }                       
                        }
                    }
                    catch (SocketException e)
                    {
    
                        clientData.clientSocket = null;                    
                        Console.WriteLine("Client disconnected!!");
                        Console.ReadLine();
                        Environment.Exit(0);                                       
                    }
                }
            }
    
            public static void DataManager(string inputFromClient, ClientData client)
            {
                if (!DataHelper.isCommandValid(inputFromClient))
                {
                    client.clientSocket.Send(System.Text.Encoding.UTF8.GetBytes("Invalid Request!"));
                    return;
                }
    
                /*foreach (ClientData c in clients)
                {
                    string clientSessionId = DataHelper.getClientSessionId(clientSocket);
    
                    if(c.sessionId == clientSessionId)
                    {*/
                        try
                        {
                            //Replace the port number in input command
                            string newCommand = DataHelper.replacePortNumberOfClientInput(inputFromClient, client.reqtifyServer.portNo);
                            Hashtable httpResponse = client.reqtifyServer.getResponseFromReqtifyServer(newCommand);
    
                            if (httpResponse.Count > 0)
                            {
                                string htmlResponse = (String)httpResponse["result"];
                                byte[] data = System.Text.Encoding.UTF8.GetBytes(htmlResponse);
                                client.clientSocket.Send(data);
    
                                if (client.sessionId == null)
                                {
                                    DataHelper.saveCookieToClient(client.clientSocket, (string)httpResponse["Cookie"]);
                                    client.sessionId = client.reqtifyServer.sessionId;
                                }
    
                                Console.WriteLine(htmlResponse);
                            }
                        } catch(WebException we)
                        {
                            Console.WriteLine(we);
                        }
                    //}               
                //}                                  
            }
    
            public static void setTimeOutMessage(object source, ElapsedEventArgs e,ClientData clientData)
            {
                Console.WriteLine("Object source:"+source);
                ((System.Timers.Timer)source).Close();
                
                byte[] data = System.Text.Encoding.UTF8.GetBytes("Session expired!!");
                clientData.clientSocket.Send(data);
    
                //close the reqtify instance
                clientData.reqtifyServer.closeTheReqtifyServerInstance();
    
                //close the client socket
                clientData.clientSocket.Close();
                clientData.timer.Stop();
    
                //destroy the client data
            }
        }
    
        public class ClientData
        {
            public Socket clientSocket;
            public Thread clientThread;
            public ReqtifyServer reqtifyServer;
            String id;
            public string sessionId;
            public int delayBeforeClosing;
            public System.Timers.Timer timer;
    
            public ClientData()
            {
                delayBeforeClosing = DataHelper.getDelayBeforeClosingSession();
                id = Guid.NewGuid().ToString();
                clientThread = new Thread(Server.Data_IN);
                clientThread.Start(this);
                //SendRegistrationPacket();
            }
    
            public ClientData(Socket clientSocket)
            {
                delayBeforeClosing = DataHelper.getDelayBeforeClosingSession();
                reqtifyServer = new ReqtifyServer();
                reqtifyServer.startReqtifyInstance(this);            
                this.clientSocket = clientSocket;
                id = Guid.NewGuid().ToString();
                clientThread = new Thread(Server.Data_IN);
                clientThread.Start(this);
                //SendRegistrationPacket();
    
                timer = new System.Timers.Timer();
                timer.Elapsed += (sender, e) => Server.setTimeOutMessage(sender, e, this);
                timer.Interval = delayBeforeClosing * 1000;
                timer.Enabled = true;
            }
    
            public void SendRegistrationPacket()
            {
                string registrationMessage = "Connection established."+" Reqtify port number is "+reqtifyServer.portNo;
                byte[] data = System.Text.Encoding.UTF8.GetBytes(registrationMessage);
                
                clientSocket.Send(data);
            }
        }
    }
    

    As you can see, method Data_IN() receives the requests from clients. 

    HttpProcessor class processes the browser request.  In above Server class, in Data_IN() method, I have called the method processClientInput() of HttpProcessor class.

    Here is my HttpProcessor class:

    using System;
    using System.IO;
    using System.Net.Sockets;
    using System.Threading;
    using System.Collections;
    using System.Text;
    using System.Net;
    
    namespace Server
    {
        public class HttpProcessor
        {
            private TcpClient tcpClient;
            private Stream inputStream;
            private StreamWriter outputStream;
            private string httpMethod;
            private string httpUrl;
            private string httpProtocolVersion;
            private Hashtable httpHeaders = new Hashtable();
            private Socket connection;
            private NetworkStream connectionStream = null;
            private BinaryReader inStream = null;
            private BinaryWriter outStream = null;
    
            public HttpProcessor(Socket clientSocket)
            {
                tcpClient = new TcpClient();
                tcpClient.Client = clientSocket;
                this.connection = clientSocket;    
            }
    
            public void processClientInput()
            {
                inputStream = new BufferedStream(new NetworkStream(connection));
                outputStream = new StreamWriter(new BufferedStream(new NetworkStream(connection)));
                
                //connectionStream = new NetworkStream(connection);
    
                try
                {
                    handleGETRequest();
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception: " + e.ToString());
                    writeFailure();
                }
                outputStream.Flush();            
                inputStream = null; outputStream = null;            
            }
    
            private string streamReadLine(Stream inputStream)
            {
                int nextChar;
                string data = "";
                while (true)
                {
                    nextChar = inputStream.ReadByte();
                    if (nextChar == '\n') { break; }
                    if (nextChar == '\r') { continue; }
                    if (nextChar == -1) { Thread.Sleep(1); continue; };
                    data += Convert.ToChar(nextChar);
                }
                return data;
            }
    
            public void parseRequest()
            {
                String request = streamReadLine(inputStream);
                string[] tokens = request.Split(' ');
                if (tokens.Length != 3)
                {
                    throw new Exception("invalid http request line");
                }
                httpMethod = tokens[0].ToUpper();
                httpUrl = tokens[1];
                httpProtocolVersion = tokens[2];
    
                Console.WriteLine("starting: " + request);
            }
    
            public void readHeaders()
            {
                Console.WriteLine("readHeaders()");
                String line;
                while ((line = streamReadLine(inputStream)) != null)
                {
                    if (line.Equals(""))
                    {
                        Console.WriteLine("got headers");
                        return;
                    }
    
                    int separator = line.IndexOf(':');
                    if (separator == -1)
                    {
                        throw new Exception("invalid http header line: " + line);
                    }
                    String name = line.Substring(0, separator);
                    int pos = separator + 1;
                    while ((pos < line.Length) && (line[pos] == ' '))
                    {
                        pos++; // strip any spaces
                    }
    
                    string value = line.Substring(pos, line.Length - pos);
                    Console.WriteLine("header: {0}:{1}", name, value);
                    httpHeaders[name] = value;
                }
            }
    
            public void writeSuccess(string content_type = "text/html")
            {
                outputStream.WriteLine("HTTP/1.0 200 OK");
                outputStream.WriteLine("Content-Type: " + content_type);            
                outputStream.WriteLine("Connection: close");
                outputStream.WriteLine("Access-Control-Allow-Origin: *");
                outputStream.WriteLine("Access-Control-Expose-Headers: auth-token");
                outputStream.WriteLine("Access-Control-Allow-Headers: *");
                outputStream.WriteLine("");
            }
    
            public void writeFailure()
            {
                outputStream.WriteLine("HTTP/1.0 404 File not found");
                outputStream.WriteLine("Connection: close");
                outputStream.WriteLine("");
            }
    
            public void handleGETRequest()
            {            
                writeSuccess();
                outputStream.WriteLine("<html><body><h1>Welcome!</h1>");
            }
    
            public void handlePOSTRequest()
            {
                writeSuccess();
                outputStream.WriteLine("<html><body><h1>Welcome!</h1>");
            }
    
            public static void HttpListener(string[] prefixes)
            {
                if (prefixes == null || prefixes.Length == 0)
                    throw new ArgumentException("Prefixes needed");
    
                HttpListener listener = new HttpListener();
    
                foreach (string s in prefixes)
                {
                    listener.Prefixes.Add(s);
                }
                listener.Start();
                Console.WriteLine("Listening..");
    
                HttpListenerContext context = listener.GetContext();
                HttpListenerRequest request = context.Request;
                HttpListenerResponse response = context.Response;
    
                string responseString = "<HTML><BODY> Test </BODY></HTML>";
                byte[] buffer = Encoding.UTF8.GetBytes(responseString);
    
                response.ContentLength64 = buffer.Length;
                Stream output = response.OutputStream;
                output.Write(buffer, 0, buffer.Length);
    
                output.Close();
                listener.Stop();
            }
        }
    }
    

    Now, when I give request from browser, it takes a lot of time and does not display the server response until I close the Server.

    Could you please tell me where I am wrong?

    Thank you in advance!

    Regards,

    Navnath

    Monday, December 11, 2017 2:03 PM

All replies

  • Hi Navnath,

    Your server program is what the project?

    I'm weirdthat you are trying to do,as far as I know, Web server and browser whether to send data or receive (analyze) data comply with the HTTP protocol.

    So how Web browser connect the Socket server and how the socket server handle the Web browser request ?

    And Do you consider WCF and websocket

    Sincerely,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    • Edited by Bob Ding Tuesday, December 12, 2017 10:50 AM
    Tuesday, December 12, 2017 10:18 AM
  • Hello Bob,

    I am using Socket. Pure Socket. No wrapper classes.

    Tuesday, December 12, 2017 12:20 PM
  • Hi,

    >> I am using Socket. Pure Socket. No wrapper classes.

    As far as I know, HTTP protocol is a non-persistent, one-way network protocol that allows the server to return the appropriate data only after the browser has made a request to the server

    So How your Web browser connect to the C# Server ?

    If you do not use websockets, do you use timers to continuously send requests to the server ?

    Sincerely,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, December 14, 2017 5:43 AM