Проблема подключения к веб-серверу C # - PullRequest
1 голос
/ 26 октября 2008

Я пытаюсь создать простой веб-сервер на C #, к которому на этом этапе вы можете получить доступ через браузер и просто выполните «Hello World».

У меня проблема в том, что сервер может нормально получать данные - я получаю информацию заголовка браузера - но браузер не получает ничего, что я отправляю. Кроме того, я могу подключиться к серверу, только перейдя на localhost (или 127.0.0.1). Я не могу добраться до него, перейдя на свой IP, и это не сетевые настройки, потому что Apache работает нормально, если я запускаю это вместо этого. Кроме того, я использую программу мониторинга портов, и после попытки подключения из браузера порт процесса застревает в состоянии TIME_WAIT, даже если я сказал, чтобы соединение закрылось, и оно должно вернуться к LISTEN.

Вот соответствующий код. Пара вызовов может не иметь смысла, но это часть большой программы.

class ConnectionHandler
{
    private Server server;

    private TcpListener tcp;

    private ArrayList connections;

    private bool listening;

    private Thread listeningThread;

    public Server getServer()
    {
        return server;
    }

    private void log(String s, bool e)
    {
        server.log("Connection Manager: " + s, e);
    }

    private void threadedListen()
    {
        while (listening)
        {
            try
            {
                TcpClient t = tcp.AcceptTcpClient();
                Connection conn = new Connection(this, t);
            }
            catch (NullReferenceException)
            {
                log("unable to accept connections!", true);
            }
        }
        log("Stopped listening", false);
    }

    public void listen()
    {
        log("Listening for new connections", false);
        tcp.Start();
        listening = true;
        if (listeningThread != null && listeningThread.IsAlive)
        {
            listeningThread.Abort();
        }
        listeningThread = new Thread(new ThreadStart(
            this.threadedListen));
        listeningThread.Start();
    }

    public void stop()
    {
        listening = false;
        if (listeningThread != null)
        {
            listeningThread.Abort();
            log("Forced stop", false);
        }
        log("Stopped listening", false);
    }

    public ConnectionHandler(Server server)
    {
        this.server = server;
        tcp = new TcpListener(new IPEndPoint(
            IPAddress.Parse("127.0.0.1"), 80));
        connections = new ArrayList();
    }
}

class Connection
{
    private Socket socket;
    private TcpClient tcp;

    private ConnectionHandler ch;

    public Connection(ConnectionHandler ch, TcpClient t)
    {
        try
        {
            this.ch = ch;
            this.tcp = t;
            ch.getServer().log("new tcp connection to " 
                + this.tcp.Client.RemoteEndPoint.ToString(), false);
            NetworkStream ns = t.GetStream();

            String responseString;
            Byte[] response;
            Int32 bytes;
            responseString = String.Empty;
            response = new Byte[512];
            bytes = ns.Read(response, 0, response.Length);
            responseString = 
                System.Text.Encoding.ASCII.GetString(response, 0, bytes);
            ch.getServer().log("Received: " + responseString);

            String msg = "<html>Hello World</html>";
            String fullMsg = "HTTP/1.x 200 OK\r\n"
                    + "Server: Test Server\r\n"
                    + "Content-Type: text/html; "
                        + "charset=UTF-8\r\n"
                    + "Content-Length: " + msg.Length + "\r\n"
                    + "Date: Sun, 10 Aug 2008 22:59:59 GMT"
                        + "\r\n";
            nsSend(fullMsg, ns);
            nsSend(msg, ns);

            ns.Close();
            tcp.Close();
        }
        catch (ArgumentNullException e)
        {
            ch.getServer().log("connection error: argument null exception: " + e);
        }
        catch (SocketException e)
        {
            ch.getServer().log("connection error: socket exception: " + e);
        }
    }

    private void nsSend(String s, NetworkStream ns)
    {
        Byte[] data = System.Text.Encoding.ASCII.GetBytes(s);
        ns.Write(data, 0, data.Length);
        ns.Flush();
        ch.getServer().log("Sent: " + s);
    }
}

У кого-нибудь есть идеи? Такое ощущение, что это должно быть что-то глупое с моей стороны, но я просто не знаю, что. Буду очень признателен за любые идеи

Ответы [ 4 ]

1 голос
/ 27 октября 2008

Возможно, вы хотели бы знать, что вы можете использовать HttpListener для написания базового веб-сервера очень легко - это касается большинства болезненных моментов, позволяя вам сосредоточиться на написании реального кода. На странице MSDN приведен пример.

Обратите внимание, что здесь используется HTTP.SYS, что хорошо, но означает, что не-администраторам должен быть явно предоставлен доступ к открытым портам; на XP вы можете сделать это с httpcfg; на Vista вы можете использовать netsh. Подробнее см. здесь .

1 голос
/ 27 октября 2008

Одна вещь, которая не является проблемой в данный момент, но может быть позже, это то, что длина вашего контента основана на Unicode длине строки сообщения, а не на двоичном длина.

В конструкторе Connection также происходит довольно много вещей - вещи, которые на самом деле не принадлежат конструктору, IMO. Это также не закрывает вещи, если происходят исключения.

Вы смотрели на то, что происходит в сетевом трассере, таком как WireShark? Это был бы самый простой способ узнать, отправляются ли любые данные обратно клиенту.

Кроме того, опубликуйте краткую, но полную версию вашего кода, которую мы можем скомпилировать и запустить самостоятельно.

0 голосов
/ 15 января 2019

Для тех, кто находится в аналогичной ситуации, когда вы хотите получить доступ к вашему серверу C # с IP-адреса локальной сети, вам нужно будет прослушать адрес 0.0.0.0, что означает прослушивание всех IP-адресов, а не определенного, например 127.0.0.1 и т. Д.

0 голосов
/ 27 октября 2008

Возможно, я просто что-то упускаю, но причина, по которой вы можете подключиться только к localhost, заключается в том, что прослушиваемый IP-адрес - 127.0.0.1, поэтому TCPListener прослушивает только этот IP-адрес. И я нигде не вижу, чтобы вы вызывали какое-либо клиентское отключение, TCPListener является блокирующим вызовом, поэтому он остается там до тех пор, пока не будет установлено соединение. В моем прошлом опыте работы с TCP / IP и TCPListener, классы TCPClient не представляли особого способа заставить слушателя разорвать соединение до тех пор, пока вы не разорвете соединение клиента. Вызов TCPListener.Abort () не сбрасывает соединение с клиентом, из-за чего порт блокируется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...