문제

이 단계에서 브라우저를 통해 액세스 할 수 있고 "Hello World"를 수행하는 간단한 C# 웹 서버를 만들려고합니다.

내가 가진 문제는 서버가 데이터를 잘 수신 할 수 있다는 것입니다. 브라우저의 헤더 정보를 얻을 수 있지만 브라우저는 내가 보내는 내용을받지 못합니다. 또한 LocalHost (또는 127.0.0.1)로 이동하여 서버에만 연결할 수 있습니다. IP로 이동하여 얻을 수 없으며 Apache가 대신 실행하면 잘 작동하기 때문에 네트워크 설정이 아닙니다. 또한 포트 모니터링 프로그램을 사용하고 있으며 브라우저에서 연결을 시도한 후 프로세스의 포트가 Time_wait 상태에 갇히게됩니다.

관련 코드는 다음과 같습니다. 몇 번의 전화는 말이되지 않을 수도 있지만 이것은 더 큰 프로그램입니다.

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);
    }
}

아무도 아이디어가 있습니까? 그것은 내 부분에 어리석은 일이 있어야한다고 생각하지만 나는 단지 무엇을 모른다. 통찰력이 정말 감사합니다

도움이 되었습니까?

해결책

사용할 수 있다는 것을 알고 싶을 수도 있습니다 HttpListener 기본 웹 서버를 매우 쉽게 작성하려면 대부분의 고통스러운 비트를 처리하여 실제 코드 작성에 집중할 수 있습니다. MSDN 페이지는 예를 제공합니다.

이것은 http.sys를 사용하는데, 이는 좋은 것입니다. 그러나 아들이 아닌 사람들은 열린 포트에 대한 접근을 명시 적으로 제공해야한다는 것을 의미합니다. XP에서는이 작업을 수행 할 수 있습니다 httpcfg; Vista에서는 사용할 수 있습니다 netsh. 보다 여기 이상.

다른 팁

현재 문제가되지 않지만 나중에있을 수있는 한 가지는 콘텐츠 길이가 유니 코드 메시지 문자열의 길이가 아닙니다 이진 길이.

연결 생성자에는 많은 일이 일어나고 있습니다. 실제로 생성자에 속하지 않는 것들, IMO. 예외가 발생하면 닫히지 않습니다.

Wireshark와 같은 네트워크 트레이서에서 무슨 일이 일어나고 있는지 보셨습니까? 그것은 가장 쉬운 방법 일 것입니다 어느 데이터가 클라이언트로 다시 전송되고 있습니다.

또는 우리가 컴파일하고 실행할 수있는 짧지 만 완전한 버전의 코드를 게시하십시오.

어쩌면 내가 뭔가 빠진 것일 수도 있지만 LocalHost에서만 연결할 수있는 이유는 당신이 듣고있는 IP가 127.0.0.1이기 때문에 tcplistener가 해당 IP 주소에서만들을 수 있기 때문입니다. 그리고 당신이 클라이언트 연결을 끊는 곳은 어디에서나 보이지 않습니다. TCP/IP 및 TCPlistener에 대한 과거의 경험에는 TCPClient 클래스 클래스 클라이언트가 클라이언트 연결을 중단 할 때까지 청취자가 연결을 삭제하도록하는 방법은 많지 않습니다. tcplistener.abort ()를 호출한다고해서 포트가 막히는 클라이언트 연결이 떨어지지 않습니다.

로컬 네트워크 IP 주소에서 C# Server에 액세스하려는 비슷한 상황에 처한 사람은 0.0.0.0 주소를 듣고 127.0.0.1 등과 같은 특정 IP 주소에서 듣기를 의미합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top