Laden...

Forcieren Socket Close

Erstellt von Ploetzi vor 14 Jahren Letzter Beitrag vor 14 Jahren 749 Views
Ploetzi Themenstarter:in
313 Beiträge seit 2006
vor 14 Jahren
Forcieren Socket Close

Hallo,
wie kann man das schliessen eines Ports beim beenden einer C# Applikation forcieren,erzwingen?
Aktuell beim beendne meines Programms rufe ich auf:

 myListener.Server.Close();
 myListener.Stop();

Wobei ab und an der Port danach beim abermaligen starten des Programms nicht geöffnet werden kann,...

Wichtig hierbei:Der Server startet immer beim Zugriff einen neuen Thread....
im Thread schaut dass dann so aus:


            while (run)
            {
                //Accept a new connection
                myListener.Start();
                Socket mySocket;
                try
                {
                    mySocket = myListener.AcceptSocket();
                }

363 Beiträge seit 2007
vor 14 Jahren

Hi,

eigentlich liegt es doch auf der Hand. Entweder du rufst Socket.CLose() auf oder du nutzt den Socket in einer Using-Anweisung


            while (run)
            {
                //Accept a new connection
                myListener.Start();
                try
                {
                    using (Socket mySocket = myListener.AcceptSocket())
                    {
                       .....
                    }
                }

Ob die Syntax jetzt 100% korrekt ist hab ich vorher nicht geprüft.

Gruß Cookiie

"Hail to the King, Baby!"

Ploetzi Themenstarter:in
313 Beiträge seit 2006
vor 14 Jahren

Nja, das funktioniert ja alles. Nur beim Beenden und neuerlichen Starten geht manchmal der Socket nicht mehr auf .

Ploetzi Themenstarter:in
313 Beiträge seit 2006
vor 14 Jahren
namespace at.xxx.WebServerMobile
{
    using System;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;


    class httpserver
    {
        private object lockobject = new object();
        private TcpListener myListener;
        bool run = true;
        private int port; // Select any free port you wish
        
       
        //The constructor which make the TcpListener start listening on the
        //given port. It also calls a Thread on the method StartListen(). 
        public httpserver()
        {
            try
            {

                    port=Convert.ToInt32(Settings.ServerPort);
                    myListener = new TcpListener(port);
                    myListener.Start();
              
                main.getInstance()._WriteLog("httpserver: Web Server Running..on Port:"+port.ToString());
                //start the thread which calls the method 'StartListen'

                Thread th = new Thread(new ThreadStart(StartListen));
                th.Start();

            }
            catch (Exception e)
            {
                 main.getInstance()._WriteLog("httpserver: An Exception Occurred while Listening :" + e.ToString());
            }
        }


        /// <summary>
        /// Returns The Default File Name
        /// Input : WebServerRoot Folder
        /// Output: Default File Name
        /// </summary>
        /// <param name="sMyWebServerRoot"></param>
        /// <returns></returns>
        public string GetTheDefaultFileName(string sLocalDirectory)
        {
            StreamReader sr;
            String sLine = "";
            try
            {
                //Open the default.dat to find out the list
                // of default file
               // sr = new StreamReader("data\\Default.Dat");
                sr = new StreamReader(main.getInstance().app_path+"\\Data\\Default.Dat");
             
                while ((sLine = sr.ReadLine()) != null)
                {
                    main.getInstance()._WriteLog(sLine);
                    //Look for the default file in the web server root folder
                    if (File.Exists(sLocalDirectory + sLine) == true)
                        break;
                }
            }
            catch (Exception e)
            {
                 main.getInstance()._WriteLog("httpserver: An Exception Occurred in GetTheDefaultFilename("+sLocalDirectory+") : " + e.ToString());
            }

            if (File.Exists(sLocalDirectory + sLine) == true)
                return sLine;
            else
                return "";
        }

        public void closeports()
        {
            run = false;
            try
            {
                myListener.Server.Close();
            }
            catch { };
            try
            {
                myListener.Stop();
               
            }
            catch { };
        }

        /// <summary>
        /// This function takes FileName as Input and returns the mime type..
        /// </summary>
        /// <param name="sRequestedFile">To indentify the Mime Type</param>
        /// <returns>Mime Type</returns>
        public string GetMimeType(string sRequestedFile)
        {


            StreamReader sr;
            String sLine = "";
            String sMimeType = "";
            String sFileExt = "";
            String sMimeExt = "";
            try
            {
            // Convert to lowercase
            sRequestedFile = sRequestedFile.ToLower();

            int iStartPos = sRequestedFile.IndexOf(".");

            sFileExt = sRequestedFile.Substring(iStartPos);

            
                //Open the Vdirs.dat to find out the list virtual directories
                //sr = new StreamReader("data\\Mime.Dat");

            sr = new StreamReader(main.getInstance().app_path + "\\Data\\Mime.Dat");
                while ((sLine = sr.ReadLine()) != null)
                {

                    sLine.Trim();

                    if (sLine.Length > 0)
                    {
                        //find the separator
                        iStartPos = sLine.IndexOf(";");

                        // Convert to lower case
                        sLine = sLine.ToLower();

                        sMimeExt = sLine.Substring(0, iStartPos);
                        sMimeType = sLine.Substring(iStartPos + 1);

                        if (sMimeExt == sFileExt)
                            break;
                    }
                }
            }
            catch (Exception e)
            {
                main.getInstance()._WriteLog("httpserver: An Exception Occurred in GetMimeType(" + sRequestedFile + ") : " + e.ToString());
            }
        
            if (sMimeExt == sFileExt)
                return sMimeType;
            else
                return "";
        }



        /// <summary>
        /// Returns the Physical Path
        /// </summary>
        /// <param name="sMyWebServerRoot">Web Server Root Directory</param>
        /// <param name="sDirName">Virtual Directory </param>
        /// <returns>Physical local Path</returns>
        public string GetLocalPath(string sMyWebServerRoot, string sDirName)
        {
            try
            {
                main.getInstance()._WriteLog("Pfad:" + sMyWebServerRoot + sDirName.Replace("/", "\\").Split('?')[0]);
                if (File.Exists(sMyWebServerRoot + sDirName.Replace("/", "\\").Split('?')[0]))
                    return sMyWebServerRoot + sDirName.Replace("/", "\\").Split('?')[0];
                if (Directory.Exists(sMyWebServerRoot + sDirName.Replace("/", "\\").Split('?')[0]))
                    return sMyWebServerRoot + sDirName.Replace("/", "\\").Split('?')[0];
                else
                    return "";
            }
            catch (Exception e)
            {
                main.getInstance()._WriteLog("httpserver: An Exception Occurred in GetLocalPath(" + sMyWebServerRoot +","+sDirName+ ") : " + e.ToString());
            }
            return "";

        }



        /// <summary>
        /// This function send the Header Information to the client (Browser)
        /// </summary>
        /// <param name="sHttpVersion">HTTP Version</param>
        /// <param name="sMIMEHeader">Mime Type</param>
        /// <param name="iTotBytes">Total Bytes to be sent in the body</param>
        /// <param name="mySocket">Socket reference</param>
        /// <returns></returns>
        public void SendHeader(string sHttpVersion, string sMIMEHeader, int iTotBytes, string sStatusCode, ref Socket mySocket)
        {
            try{
            String sBuffer = "";

            // if Mime type is not provided set default to text/html
            if (sMIMEHeader.Length == 0)
            {
                sMIMEHeader = "text/html";  // Default Mime Type is text/html
            }

            sBuffer = sBuffer + sHttpVersion + sStatusCode + "\r\n";
            sBuffer = sBuffer + "Server: cx1193719-b\r\n";
            sBuffer = sBuffer + "Content-Type: " + sMIMEHeader + "\r\n";
            sBuffer = sBuffer + "Accept-Ranges: bytes\r\n";
            sBuffer = sBuffer + "Content-Length: " + iTotBytes + "\r\n\r\n";
            main.getInstance()._WriteLog("sent header:" + sBuffer);
            Byte[] bSendData = Encoding.ASCII.GetBytes(sBuffer);

            SendToBrowser(bSendData, ref mySocket);

             main.getInstance()._WriteLog("httpserver  Total Bytes : " + iTotBytes.ToString());
            }
            catch (Exception e)
            {
                main.getInstance()._WriteLog("httpserver: An Exception Occurred in SendHeader(" + sHttpVersion + "," + sMIMEHeader + "," + iTotBytes.ToString() + "," + sStatusCode + ") : " + e.ToString());
            }
        }

        private static httpserver instance;
        public static httpserver getInstance()
        {
            if (instance == null)
                instance = new httpserver();
            return instance;
        }
      

        /// <summary>
        /// Overloaded Function, takes string, convert to bytes and calls 
        /// overloaded sendToBrowserFunction.
        /// </summary>
        /// <param name="sData">The data to be sent to the browser(client)</param>
        /// <param name="mySocket">Socket reference</param>
        public void SendToBrowser(String sData, ref Socket mySocket)
        {
            SendToBrowser(Encoding.ASCII.GetBytes(sData), ref mySocket);
        }



        /// <summary>
        /// Sends data to the browser (client)
        /// </summary>
        /// <param name="bSendData">Byte Array</param>
        /// <param name="mySocket">Socket reference</param>
        public void SendToBrowser(Byte[] bSendData, ref Socket mySocket)
        {
            main.getInstance()._WriteLog("send to browser size" + bSendData.Length.ToString());
            int numBytes = 0;

            try
            {
                if (mySocket.Connected)
                {
                    if ((numBytes = mySocket.Send(bSendData, bSendData.Length, 0)) == -1)
                         main.getInstance()._WriteLog("httpserver: Socket Error cannot Send Packet");
                    else
                    {
                         main.getInstance()._WriteLog("httpserver: No. of bytes send "+numBytes.ToString());  
                    }
                }
                else
                     main.getInstance()._WriteLog("httpserver: Connection Dropped....");
            }
            catch (Exception e)
            {
                 main.getInstance()._WriteLog("httpserver: SendToBrowser("+bSendData.ToString()+")Error Occurred :  "+e.ToString());

            }
        }


        public static byte[] ReadFully(Stream stream, int initialLength)
        {
            // If we've been passed an unhelpful initial length, just
            // use 32K.
            if (initialLength < 1)
            {
                initialLength = 32768;
            }

            byte[] buffer = new byte[initialLength];
            int read = 0;

            int chunk;
            while ((chunk = stream.Read(buffer, read, buffer.Length - read)) > 0)
            {
                read += chunk;

                // If we've reached the end of our buffer, check to see if there's
                // any more information
                if (read == buffer.Length)
                {
                    int nextByte = stream.ReadByte();

                    // End of stream? If so, we're done
                    if (nextByte == -1)
                    {
                        return buffer;
                    }

                    // Nope. Resize the buffer, put in the byte we've just
                    // read, and continue
                    byte[] newBuffer = new byte[buffer.Length * 2];
                    Array.Copy(buffer, newBuffer, buffer.Length);
                    newBuffer[read] = (byte)nextByte;
                    buffer = newBuffer;
                    read++;
                }
            }
            // Buffer is now too big. Shrink it.
            byte[] ret = new byte[read];
            Array.Copy(buffer, ret, read);
            return ret;
        }




        //This method Accepts new connection and
        //First it receives the welcome massage from the client,
        //Then it sends the Current date time to the Client.
        public void StartListen()
        {

            int iStartPos = 0;
            String sRequest;
            String sDirName;
            String sRequestedFile;
            String sErrorMessage;
            String sLocalDir;
            String sMyWebServerRoot = main.getInstance().app_path + "\\MyWebServerRoot\\";
            String sPhysicalFilePath = "";
            String sFormattedMessage = "";
            String sResponse = "";

            while (run)
            {
                //Accept a new connection
                myListener.Start();
                Socket mySocket;
                try
                {
                    mySocket = myListener.AcceptSocket();
                }
                catch
                {
                    mySocket = new Socket(AddressFamily.InterNetwork,  SocketType.Stream,    ProtocolType.Tcp);
                    main.getInstance()._WriteLog("httpserver wollte Socket offnen aber beendet gerade");
                }
                  
               
                // main.getInstance()._WriteLog("httpserver: Socket Type " + mySocket.SocketType);
              
                if (mySocket.Connected)
                {
                   
                    main.getInstance()._WriteLog("httpserver: \nClient Connected!!\n==================\nCLient IP \n" +
                       mySocket.RemoteEndPoint.ToString());
                    //make a byte array and receive data from the client 
                    Byte[] bReceive = new Byte[1024];
                    string sBuffer="";
                    try
                    {
                        int i = mySocket.Receive(bReceive, bReceive.Length, 0);
                  
                    //Convert Byte to String
                     sBuffer = Encoding.ASCII.GetString(bReceive, 0, bReceive.Length);
                     main.getInstance()._WriteLog(sBuffer);
                    }
                    catch (Exception e)
                    {
                        main.getInstance()._WriteLog("httpserver: An Exception  :" + e.ToString());
                    }
                    try
                    {
                        //Not just a socket opened
                        if (sBuffer.Length > 5)
                        {
                            if (main.getInstance().TestmodusValue )
                            {
                                main.getInstance()._WriteLog("httpserver: Init not finished");
                                string sHttpVersion = sBuffer.Substring(iStartPos, 8);
                                string Message = "<html><body><center><meta http-equiv=\"refresh\" content=\"5; URL=index.html?time="+DateTime.Now.ToString()+"\"><font face=Arial>Init not finished.<br>Loading Login screen after finishing.</font></center></body></html>";

                                SendToBrowser(Message, ref mySocket);
                                mySocket.Close();
                            }
                            else if ((!sBuffer.Contains("BC84SIM") && !sBuffer.Contains("WebApp") && (sBuffer.Contains("iPod") || sBuffer.Contains("iPhone") )) )
                            {
                                main.getInstance()._WriteLog("httpserver: Iphonemodus");
                                string sHttpVersion = sBuffer.Substring(iStartPos, 8);
                                string Message = "<html><body><center><meta http-equiv=\"refresh\" content=\"0; URL=/WebApp/index.html?time=" + DateTime.Now.ToString() + "\"><font face=Arial>Loading Iphone GUI....</font></center></body></html>";

                                SendToBrowser(Message, ref mySocket);
                                mySocket.Close();
                            }
                            else
                            {
                                // Look for HTTP request
                                iStartPos = sBuffer.IndexOf("HTTP", 1);
                                string sHttpVersion = sBuffer.Substring(iStartPos, 8);
                                sRequest = sBuffer.Substring(0, iStartPos - 1);
                                if (sBuffer.StartsWith("GET /settings/brand/"))
                                {
                                    main.getInstance()._WriteLog("httpserver: Settings Brand");
                                    string Message = Settings.BrandSB;
                                   // Message = MyLoginHandler.getInstance().checklogin(sBuffer, mySocket.RemoteEndPoint.ToString().Split(':')[0]);
                                    SendHeader(sHttpVersion, "text/xml", Message.Length, " 200 OK", ref mySocket);
                                    SendToBrowser(Message, ref mySocket);
                                    mySocket.Close();
                                }
                                //Login
                                else if (sBuffer.StartsWith("GET /login/"))
                                {
                                    main.getInstance()._WriteLog("httpserver: Loginmodus");
                                    string Message="";
                                    Message = MyLoginHandler.getInstance().checklogin(sBuffer, mySocket.RemoteEndPoint.ToString().Split(':')[0]);
                                    SendHeader(sHttpVersion, "text/xml", Message.Length, " 200 OK", ref mySocket);
                                    SendToBrowser(Message, ref mySocket);
                                    mySocket.Close();     
                                }else
                                if (sBuffer.StartsWith("GET /logout/"))
                                {
                                    main.getInstance()._WriteLog("httpserver: Logoutmodus");
                                    string Message = "Error: Ausgeloggt";
                                    MyLoginHandler.getInstance().logout(sBuffer, mySocket.RemoteEndPoint.ToString().Split(':')[0]);
                                    SendHeader(sHttpVersion, "text/xml", Message.Length, " 200 OK", ref mySocket);

                                    SendToBrowser(Message, ref mySocket);
                                    mySocket.Close();
                                }

                                //At present we will only deal with GET type
                                else if (sBuffer.Substring(0, 20).Contains("/request/") 
                                    || sBuffer.Substring(0, 20).Contains("/BC84SIM/") || sBuffer.Substring(0, 20).Contains("/ipadresse/"))
                                {
                                    main.getInstance()._WriteLog("httpserver: Requestmodus");
                                    if (MyLoginHandler.getInstance().loggedin(sBuffer, mySocket.RemoteEndPoint.ToString().Split(':')[0]))
                                    {
                                        string Message;
                                        try
                                        {
                                            lock (lockobject)
                                            {
                                                Message = MyEventHandler.getInstance().UseGeneral(sRequest);
                                            }
                                            if (sBuffer.Substring(0, 20).Contains("BC84"))
                                            {
                                                main.getInstance()._WriteLog("html");
                                                SendHeader(sHttpVersion, "", Message.Length, " 200 OK", ref mySocket);
                                            }
                                            else
                                            {

                                                main.getInstance()._WriteLog("xml");
                                                SendHeader(sHttpVersion, "text/xml", Message.Length, " 200 OK", ref mySocket);
                                            }
                                            SendToBrowser(Message, ref mySocket);
                                            mySocket.Close();
                                        }
                                        catch (Exception e)
                                        {
                                            main.getInstance()._WriteLog("httpserver: Error: Could not send dynamic data:" + e.ToString());
                                        }
                                    }
                                    else
                                    {

                                        string Message = "<channel><error>Error: Timeout of User Login</error></channel>";
                                        SendHeader(sHttpVersion, "text/xml", Message.Length, " 200 OK", ref mySocket);
                                        SendToBrowser(Message, ref mySocket);
                                        mySocket.Close();    
                                    }
                                }
                                else
                                {
                                    main.getInstance()._WriteLog("httpserver: Filemodus");
                                    //Replace backslash with Forward Slash, if Any
                                    sRequest.Replace("\\", "/");
                                    //If file name is not supplied add forward slash to indicate 
                                    //that it is a directory and then we will look for the 
                                    //default file name..
                                    if ((sRequest.IndexOf(".") < 1) && (!sRequest.EndsWith("/")))
                                    {
                                        sRequest = sRequest + "/";
                                    }
                                    //Extract the requested file name
                                    iStartPos = sRequest.LastIndexOf("/") + 1;
                                    sRequestedFile = sRequest.Substring(iStartPos);
                                    //?time argument erlauben
                                    sRequestedFile=sRequestedFile.Split('?')[0];
                                    //Extract The directory Name
                                    sDirName = sRequest.Substring(sRequest.IndexOf("/"), sRequest.LastIndexOf("/") - 3);
                                    /////////////////////////////////////////////////////////////////////
                                    // Identify the Physical Directory
                                    /////////////////////////////////////////////////////////////////////
                                    if (sDirName == "/")
                                        sLocalDir = sMyWebServerRoot;
                                    else
                                        sLocalDir = GetLocalPath(sMyWebServerRoot, sDirName);

                                    main.getInstance()._WriteLog("httpserver: Directory Requested : " + sLocalDir);

                                    //If the physical directory does not exists then
                                    // dispaly the error message
                                    if (sLocalDir.Length == 0)
                                    {
                                        sErrorMessage = "<H2>Error!! Requested Directory does not exists</H2><Br>";

                                        //sErrorMessage = sErrorMessage + "Please check data\\Vdirs.Dat";
                                        try
                                        {
                                            //Format The Message
                                            SendHeader(sHttpVersion, "", sErrorMessage.Length, " 404 Not Found", ref mySocket);
                                            //Send to the browser
                                            SendToBrowser(sErrorMessage, ref mySocket);
                                        }
                                        catch (Exception e)
                                        {
                                            main.getInstance()._WriteLog("httpserver: An Exception in sending 404 " + e.ToString());
                                        }

                                        mySocket.Close();
                                        continue;
                                    }


                                    /////////////////////////////////////////////////////////////////////
                                    // Identify the File Name
                                    /////////////////////////////////////////////////////////////////////

                                    //If The file name is not supplied then look in the default file list
                                    if (sRequestedFile.Length == 0)
                                    {
                                        // Get the default filename
                                        sRequestedFile = GetTheDefaultFileName(sLocalDir);

                                        if (sRequestedFile == "")
                                        {
                                            sErrorMessage = "<H2>Error!! No Default File Name Specified</H2>";
                                            SendHeader(sHttpVersion, "", sErrorMessage.Length, " 404 Not Found", ref mySocket);
                                            SendToBrowser(sErrorMessage, ref mySocket);

                                            mySocket.Close();

                                            return;

                                        }
                                    }




                                    /////////////////////////////////////////////////////////////////////
                                    // Get TheMime Type
                                    /////////////////////////////////////////////////////////////////////

                                    String sMimeType = GetMimeType(sRequestedFile);

                                    //Build the physical path
                                    sPhysicalFilePath = sLocalDir + sRequestedFile;
                                    main.getInstance()._WriteLog("httpserver: File Requested : " + sPhysicalFilePath);
                                    //Request of file allowed
                                    bool allowrequest = true;
                                    if (sRequestedFile.Contains("ndex.html"))
                                    {
                                        if (MyLoginHandler.getInstance().loggedin(sBuffer, mySocket.RemoteEndPoint.ToString().Split(':')[0]))
                                        {
                                            main.getInstance()._WriteLog("httpserver: Bereits eingeloggt -Weiterleitung");
                                            
                                           // string sHttpVersion = sBuffer.Substring(iStartPos, 8);
                                            string Message = "<html><body><center><meta http-equiv=\"refresh\" content=\"1; URL=index4.html?time=" + DateTime.Now.ToString() + "\"><font face=Arial>Loading...</font></center></body></html>";

                                            SendToBrowser(Message, ref mySocket);
                                            mySocket.Close();
                                        }

                                    }else
                                    if (!sRequestedFile.Contains("ndex.html") &&sRequestedFile.Contains(".html") )
                                    {
                                        if(!MyLoginHandler.getInstance().loggedin(sBuffer, mySocket.RemoteEndPoint.ToString().Split(':')[0]))
                                        allowrequest = false;
                                        
                                    }
                                    if (allowrequest == false && !sRequestedFile.Contains("ndex.html"))
                                    {
                                        main.getInstance()._WriteLog("httpserver: Noch nicht eingeloggt -Weiterleitung");
                                     
                                        //string sHttpVersion = sBuffer.Substring(iStartPos, 8);
                                        string Message = "<html><body><center><meta http-equiv=\"refresh\" content=\"1; URL=index.html?time=" + DateTime.Now.ToString() + "\"><font face=Arial>Loading...</font></center></body></html>";

                                        SendToBrowser(Message, ref mySocket);
                                        mySocket.Close();
                                    }
                                    else if (File.Exists(sPhysicalFilePath) == false)
                                    {

                                        sErrorMessage = "<H2>404 Error! File Does Not Exists...</H2>";
                                        SendHeader(sHttpVersion, "", sErrorMessage.Length, " 404 Not Found", ref mySocket);
                                        SendToBrowser(sErrorMessage, ref mySocket);

                                        Console.WriteLine(sFormattedMessage);
                                    }

                                    else 
                                    {
                                        int iTotBytes = 0;
                                        sResponse = "";
                                       FileStream fs = new FileStream(sPhysicalFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                                       byte[] bytes = ReadFully(fs, 0);
                                        iTotBytes = bytes.Length;
                                        fs.Close();
                                        SendHeader(sHttpVersion, sMimeType, iTotBytes, " 200 OK", ref mySocket);
                                   
                                        SendToBrowser(bytes, ref mySocket);

                                        //mySocket.Send(bytes, bytes.Length,0);

                                    }
                                    mySocket.Close();
                                }
                            }
                        }
                        else
                            mySocket.Close();
                    }
                    catch (Exception e)
                    {
                        main.getInstance()._WriteLog("httpserver: An Exception Occurred while Listening :" + e.ToString());
                    }
                }
            }
        }
    }
}

Das closeports wird extern von der main.cs aufgerufen.