none
請問TcpListener在Console下可以正常執行但在Service就不能接聽是什麼問題 RRS feed

  • 問題

  • 小弟使用TcpListener接收一些字串資料,經過一連串處理後,再回傳給Client;使用.Net C# 的Console應用程式,可以正常run。但是改寫成Windows Service之後,服務可以正常起來,但是卻無法接受Client連線。
    請教各位前輩們,這是什麼樣的問題。謝謝。

    這是Service OnStart的程式碼
    protected override void OnStart(string[] args)
            {
                tcp = new TCPListener();
                td = new Thread(new ThreadStart(tcp.StartListen));
                td.Name = "TCPListener";
                td.Start();
            }

    2009年4月21日 上午 06:19

解答

  • 感謝各位回覆,小弟已經發現問題所在。
    原來當在console模式下Run TcpListener時,不會被防火牆擋住,但是在Service下,防火牆會擋住。
    所以只要把防火牆開個洞,讓TcpListener可以監聽到port,這樣就可以解決了。
    還是感謝各位的幫忙。
    • 已標示為解答 皇甫群 2009年4月22日 上午 02:47
    • 已取消標示為解答 皇甫群 2009年4月22日 上午 02:48
    • 已標示為解答 皇甫群 2009年4月22日 上午 02:48
    2009年4月22日 上午 02:47

所有回覆

  • 皇甫群:
              tcp = new TCPListener(); 這行就有點奇怪了. TCPListener沒有無參數多載吧?

    2009年4月21日 上午 10:21
    版主
  • TCPListener 是小弟自己寫的一個 Class
    裡面有呼叫 TcpListener
    這邊是有傳入 ip 跟 port
    只是 TCPListener 的名稱與 TcpListener 相似度太高
    讓您誤會了 不好意思

    以下為小弟自己寫的class TCPListener 方法 StartListen


            public void StartListen()
            {
                // TODO: 在此加入啟動服務的程式碼。
                int port = Convert.ToInt32(ConfigurationManager.AppSettings["ServerPort"].ToString());
                IPAddress ip = IPAddress.Parse(ConfigurationManager.AppSettings["SeverIP"].ToString());
                listener = new TcpListener(ip, port);
                listener.Start();

                string enentLogSource = ConfigurationManager.AppSettings["EventLogSource"].ToString();
                string eventLogName = ConfigurationManager.AppSettings["EventLogName"].ToString();

                if (EventLog.Exists(eventLogName) == false)
                    EventLog.CreateEventSource(enentLogSource, eventLogName);

                EventLog eventLog = new EventLog(eventLogName);
                eventLog.Source = enentLogSource;

                eventLog.WriteEntry("IQC Data Collect Service Start. ");
                while (true)
                {
                    try
                    {
                        TcpClient client = listener.AcceptTcpClient();
                        ClientHandler ch = new ClientHandler(client);
                        eventLog.WriteEntry("Accept Client Connection:" + ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString());
                        Thread td = new Thread(new ThreadStart(ch.StartHandler));
                        td.Start();
                    }
                    catch (Exception E)
                    {
                        eventLog.WriteEntry("Error due to :" + E.Message);
                    }
                }
            }

    2009年4月21日 上午 10:27
  • 我也用Service寫過類似的程式,不過是用Socket類別,你的程式看起來還滿正常.
    問個問題,Evenlog中,已經Log到哪個步驟了?
    是到  eventLog.WriteEntry("IQC Data Collect Service Start. ");
    還是  eventLog.WriteEntry("Accept Client Connection:" + ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString());

    2009年4月21日 上午 10:46
    版主
  • 只到 eventLog.WriteEntry("IQC Data Collect Service Start. "); 這裡

    2009年4月21日 上午 11:38
  • 一步步來,在Service啟動之後,先使用netstat -a看一下預期中的Port有進入listen的狀態嗎?
    Client連結時指定的IP & Port是否正確,Client未連上是否有任何的錯誤訊息產生?
    2009年4月21日 下午 02:36
    版主
  • 
    

    Service Debug 有點麻煩,  你可以用 #if DEBUG ...    使用Debug Mode 對Service Application 除錯,

                IPAddress ip = IPAddress.Parse(ConfigurationManager.AppSettings["SeverIP"].ToString());
                listener = new TcpListener(ip, port);  //可能有關係,改用IPAddress.Any ?


      

    • 已編輯 HikaruGo 2009年4月21日 下午 04:40 change
    2009年4月21日 下午 04:28
  • 感謝各位回覆,小弟已經發現問題所在。
    原來當在console模式下Run TcpListener時,不會被防火牆擋住,但是在Service下,防火牆會擋住。
    所以只要把防火牆開個洞,讓TcpListener可以監聽到port,這樣就可以解決了。
    還是感謝各位的幫忙。
    • 已標示為解答 皇甫群 2009年4月22日 上午 02:47
    • 已取消標示為解答 皇甫群 2009年4月22日 上午 02:48
    • 已標示為解答 皇甫群 2009年4月22日 上午 02:48
    2009年4月22日 上午 02:47