麻雀雖小,五髒俱全-C# 建立windows服務、socket通訊執行個體

來源:互聯網
上載者:User

      本人一直以來都是一個實踐主義者,認為在實踐中學習,是最好的學習方式。所以在部落格中添加文章的時候,總是習慣寫一些具體實現的技術知識點。感覺這些東西可以更好的協助那些學習使用.net c#進行開發開發人員。雖然自己的文筆不好,知識的應用也很漸顯,但是本著互相學習的精神,希望在總結的同時可以加深自己的理解,考效自己對各個知識的瞭解程度,共同提高。

言歸正傳,我今天要說的就是一個windows 服務結合 Soctket、郵件發送、簡訊發送的小應用。功能不大,但是用到的.net下的知識點很多,我感覺對初步接觸這幾個相關知識的朋友還是有學習意義的。

這個功能來源於一個監看資料夾的需求:

1、 輪詢監看資料夾內檔案的狀態

2、 在發現異常後通過郵件和簡訊的方式通知管理員。

3、 在有外網環境下使用郵件方式通知。

4、 無外網情況下,通過區域網路中一台帶有的簡訊裝置電腦傳送簡訊提醒。

 

在經過具體的功能分析後,將功能劃分為4個小功能單元:

1、  運用c#開發windows服務來實現對檔案夾的輪詢監視。

2、  引用.net架構內的system.net.mail 命名控制項的下的郵件處理類來實現郵件的發送。

3、  區域網路內採用scoket解決區域網路內簡訊裝置電腦與監控電腦之間的通訊問題。

4、  C#對簡訊裝置進行簡單必要的二次開發。

 

一、windows服務實現輪詢監視

Windows 服務,以前的NT服務,都是被作為Windows NT作業系統的一部分引進來的。你需要使用NT層級的作業系統才可運行Windows服務,諸如:Windows NT、Windows 2000 Professional、windows XP或Windows 2000 Server以上作業系統。舉例而言,以Windows服務形式的產品有:Microsoft Exchange、SQL Server,還有別的如設定電腦時鐘的Windows Time服務。它隨 Windows 作業系統啟動而啟動的,在後台啟動並執行,通常不和使用者產生互動的程式。

在.net架構下建立Windows 服務非常的簡單快捷,它封裝了Windows服務程式的建立和控制過程,程式相關的命名空間涉及到以下兩個:System.ServiceProcess和System.Diagnostics。

    首先是建立windows服務,在.net架構中直接建立windows服務項目即可,在服務啟動事件中添加必要的邏輯處理。〔實現見下代碼〕

 

protected override void OnStart(string[] args)
{
// TODO: 在此處添加代碼以啟動服務。
//讀取配置資訊
ReadConfig();

timer1.Elapsed+=new System.Timers.ElapsedEventHandler(timer1_Elapsed);
timer1.Interval = GlobalInfo.TimeInterval;
timer1.Start();
}

void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{

DirectoryInfo dirs = new DirectoryInfo(GlobalInfo.DirName);
int count=0;
switch (GlobalInfo.Type)
{
case 0://延遲時間
foreach (FileInfo var in dirs.GetFiles())
{
DateTime createTime = var.CreationTime;
if (System.DateTime.Now > createTime.AddHours(GlobalInfo.Size))
count++;
}
if (count > 0)
MessageSender.Send(GlobalInfo.Norm > 1 ? false : true, string.Format("{0}個資料檔案延遲超過{1}小時,請關注。[報告時間:{2}]", count.ToString(), GlobalInfo.Size.ToString(), System.DateTime.Now.ToString()));
break;
case 1://延時資料包個數
count = dirs.GetFiles().Length;
if (count > GlobalInfo.Count)
MessageSender.Send(GlobalInfo.Norm > 1 ? false : true, string.Format("同時有{0}個資料檔案滯留,請關注。[報告時間:{1}]", count.ToString(), System.DateTime.Now.ToString()));
break;
default:
break;
}
}

 

 

二、郵件發送功能

在以前的一篇文章中提到過郵件類的使用,所以就不在作詳細說明了。〔附代碼:見下〕

  static void  Send(string titel,string megHtml,string subject)        {            string meg = "";            //寄件者            string smtpAuthUsername = GlobalInfo.SenderAddr;            //寄件者密碼            string smtpAuthPassword = GlobalInfo.SenderPwd;            //發送伺服器            string smtpServer = GlobalInfo.SmtpServer;            string objEmail = GlobalInfo.ObjAddr;            //定義傳輸協議             System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient(smtpServer);            //設定認證寄件者             smtp.Credentials = new System.Net.NetworkCredential(smtpAuthUsername, smtpAuthPassword);            //非同步發送完成擷取發送狀態             smtp.SendCompleted += new System.Net.Mail.SendCompletedEventHandler(SendCompletedCallback);            try            {                System.Net.Mail.MailMessage mail = new System.Net.Mail.MailMessage();                mail.From = new System.Net.Mail.MailAddress(smtpAuthUsername, smtpAuthUsername);                //回複人,回複人名                 mail.ReplyTo = new System.Net.Mail.MailAddress(smtpAuthUsername, smtpAuthUsername);                //收件者                 mail.To.Add(objEmail);                //郵件優先順序                 mail.Priority = System.Net.Mail.MailPriority.Normal;                //設定html郵件                 mail.IsBodyHtml = true;                //標題                 mail.Subject = titel;                //內容                 mail.Body = megHtml;                smtp.Send(mail);                meg = string.Format("{0} {1}郵件發送成功。", System.DateTime.Now.ToString(), objEmail);                WriteLog(meg);            }            catch            {                meg = string.Format("{0} {1}郵件發送失敗。", System.DateTime.Now.ToString(), objEmail);                WriteLog(meg);            }        }

三、區域網路內Socket通訊

  Socket原意是“插座”。應用程式層通過傳輸層進行資料通訊時,TCP和UDP會遇到同時為多個應用程式進程提供並發服務的問題。多個TCP串連或多個應用程式進程可能需要通過同一個TCP協議連接埠傳輸資料。為了區別不同的應用程式進程和串連,許多電腦作業系統為應用程式與TCP/IP協議互動提供了稱為通訊端(Socket)的介面,區分不同應用程式進程間的網路通訊和串連。 產生通訊端,主要有3個參數:通訊的目的IP地址、使用的傳輸層協議(TCP或UDP)和使用的連接埠號碼。通過將這3個參數結合起來,與一個“插座”Socket綁定,應用程式層就可以和傳輸層通過通訊端介面,區分來自不同應用程式進程或網路連接的通訊,實現資料轉送的並發服務。 Socket可以看成在兩個程式進行通訊串連中的一個端點,一個程式將一段資訊寫入Socket中,該Socket將這段資訊發送給另外一個Socket中,使這段資訊能傳送到其他程式中。

  因為現有的簡訊裝置位與區域網路內的另外一台伺服器上,所以需要在簡訊通知狀態下,需要將資訊發送到區域網路內另一台電腦。用socket通訊的話需要一個接收資訊的用戶端。並且用戶端需要一些參數的設定。比如:接收電話號碼、開機啟動、通訊電腦IP、等。〔資訊接收代碼見下〕

 

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);             try            {                socket.Bind(new IPEndPoint(IPAddress.Parse(Info.IP), int.Parse(Info.PORT)));                socket.Listen((int)SocketOptionName.MaxConnections);                while (true)                {                    Socket a = socket.Accept();                    if (a.Connected)                    {                        byte[] stream = new byte[80];                        a.Receive(stream);                        string message = System.Text.Encoding.UTF8.GetString(stream);                        InsertRechText ins = new InsertRechText(Insert);                        Invoke(ins, new object[] { message });                    }                    if (isover)                        return;                }            }            catch (Exception ex)            {                WriteLog(string.Format("接收資訊失敗。[{0}]", ex.Message));                throw ex;            }            finally            {                socket.Close();            }

四、簡訊裝置二次開發

簡訊裝置用的是人大金倉的DG-C1A 簡訊貓。該硬體有對應的二次開發類庫,開發很簡單。直接將引用方法封裝成一個類的靜態方法。用的時候直接調用就可以了。(直接貼出代碼)

 

  [DllImport("GSMMultiPort.dll",             EntryPoint = "GSMModemInit",             CharSet = CharSet.Ansi,             CallingConvention = CallingConvention.StdCall)]        public static extern bool GSMModemInit(            string device,            string baudrate,            string initstring,            string charset,            bool swHandshake,            string sn);//傳送簡訊息        [DllImport("GSMMultiPort.dll",             EntryPoint = "GSMModemSMSsend",             CharSet = CharSet.Ansi,             CallingConvention = CallingConvention.StdCall)]        public static extern bool GSMModemSMSsend(            string device,            string serviceCenterAddress,            int encodeval,            string text,            int textlen,            string phonenumber,            bool requestStatusReport);  //取得錯誤資訊        [DllImport("GSMMultiPort.dll",             EntryPoint = "GSMModemGetErrorMsg",             CharSet = CharSet.Ansi,             CallingConvention = CallingConvention.StdCall)]        public static extern string GSMModemGetErrorMsg(string device);

 

在完成功能後,部署,運行效果不錯。感覺這個功能雖然很小。但是用到的知識可不少,感覺還是有所收穫的。畢竟術業有專攻,每個人在從事的行業開發中專註的技術也是有限的。多學點各個方面的知識對自己的成長還是很有好處的。哈哈.〔囉嗦了〕。共同學習吧。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.