自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Mozilla Thunderbird的擴展開發(fā)

運維 系統(tǒng)運維
觸發(fā)事件可以在我們自己的MFC子程序中模擬目標程序中的事件。Mozilla平臺下如何擴展Thunderbird,本文主要講的是,通過socket通信來實現(xiàn)MFC對Thunderbird的控制需求。

  最近遇到這樣一個需求:在我們的MFC程序中控制Thunderbird。拿到這個奇怪的需求后,有了這么幾個想法:1)用全局鉤子試著勾住Thunderbird,可細想好像不對。2)用spy++探查點擊Thunderbird的各個菜單,按鈕時觸發(fā)的事件,總歸是win32平臺上跑的程序,歸根到底還是事件觸發(fā),從理論上說應(yīng)該是可以在我們自己的MFC程序中模擬標目程序中的各個事件觸發(fā)。

  但接觸到Mozilla的socket方面的知識后,放棄了上面的想法,改用socket通信來實現(xiàn)此需求。一來Thunderbird源代碼可以自行修改,因此可以加入一些代碼使之成為一個類似HTTP服務(wù)器的服務(wù)器端程序,二來使用socket進行連接與語言無關(guān),因此C++的程序可以和javascript的程序完成通信,但缺點也很明顯,要占用端口,只涉及到本地機器的通信卻使用了socket這樣的網(wǎng)絡(luò)通信機制。

  先來介紹下完成這個功能用到的基本知識:由于輸入流基接口nsIInputStream沒有提供任何從javascript中讀取數(shù)據(jù)的方法,而只能在C++中讀取,因此我們必須使用一個可腳本化的輸入流來對其進行包裝,這個可腳本化的輸入流實現(xiàn)了nsIScriptableInputStream接口。

  當然也可以使用其他流類型,比如為了讀取二進制數(shù)據(jù),我們可以使用nsIBinaryInputStream,反正在javascript中,你總得以其他形式的流來包裝基流。

  在Mozilla中,網(wǎng)絡(luò)數(shù)據(jù)的讀和寫是在一個單獨的線程中進行的,從socket中讀數(shù)據(jù)是異步的,這就意味著只要socket中有數(shù)據(jù)存在,就在后臺讀取數(shù)據(jù),而程序會收到數(shù)據(jù)可讀的通知信息,這就意味著我們需要創(chuàng)建一個監(jiān)聽者來監(jiān)聽這個信息。

  對于異步讀取數(shù)據(jù),我們還需要創(chuàng)建一個輸入流Pump,之所以Mozilla選擇“泵”這個名稱是因為當有數(shù)據(jù)存在時它就發(fā)送小塊的數(shù)據(jù)給監(jiān)聽者。這個Pump實現(xiàn)了nsIInputStreamPump接口,這個接口繼承自nsIRequest,后者提供了暫停連接和特定的緩存行為(這些一般的socket程序用不上,但像HTTP這樣構(gòu)建在socket上的高層次應(yīng)用會用得上的)。

  pump.asyncRead(dataListener,null);

  asyncRead函數(shù)用來給Pump對象設(shè)置一個監(jiān)聽者,當有數(shù)據(jù)到來或連接關(guān)閉時,監(jiān)聽者就會被調(diào)用。監(jiān)聽者對象應(yīng)該實現(xiàn)nsIStreamListener接口,這個接口有一個方法onDataAvailable,當有額外數(shù)據(jù)可讀時就會被調(diào)用。此接口繼承自nsIRequestObserver,這個接口有兩個方法,onStartRequest,onStopRequest,這兩個方法在輸入流的開始和結(jié)束時分別被調(diào)用,因此這3個方法都應(yīng)該實現(xiàn)。

  下面是客戶端代碼,使用最簡單的阻塞式TCP連接:

  

  1. void CClientTestDlg::OnSend()  
  2.  
  3.   {//發(fā)送按鈕  
  4.  
  5.   UpdateData();  
  6.  
  7.   if(str.IsEmpty())  
  8.  
  9.   {  
  10.  
  11.   list.InsertString(0,"發(fā)送的字符串不能為空。");  
  12.  
  13.   return;  
  14.  
  15.   }  
  16.  
  17.   //strcpy(msg.msg,(LPCTSTR)str);  
  18.  
  19.   char szText[1024];  
  20.  
  21.   strcpy(szText,(LPCTSTR)str);  
  22.  
  23.   SOCKET socket = ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);  
  24.  
  25.   if(socket==INVALID_SOCKET)  
  26.  
  27.   {  
  28.  
  29.   list.InsertString(0,"創(chuàng)建socket發(fā)生錯誤。");  
  30.  
  31.   return;  
  32.  
  33.   }  
  34.  
  35.   SOCKADDR_IN servAddr;  
  36.  
  37.   servAddr.sin_family = AF_INET;  
  38.  
  39.   servAddr.sin_port = htons(25501);  
  40.  
  41.   servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");  
  42.  
  43.   if(::connect(socket,(sockaddr*)&servAddr,sizeof(servAddr))==-1)  
  44.  
  45.   {  
  46.  
  47.   list.InsertString(0,"連接服務(wù)器發(fā)生錯誤。");  
  48.  
  49.   return;  
  50.  
  51.   }  
  52.  
  53.   if(::send(socket,szText,strlen(szText),0) == SOCKET_ERROR)// recv(ServerSocket,buf,sizeof(buf),0);  
  54.  
  55.   {  
  56.  
  57.   list.InsertString(0,"發(fā)送數(shù)據(jù)發(fā)生錯誤。");  
  58.  
  59.   return;  
  60.  
  61.   }  
  62.  
  63.   int bytesRecv = SOCKET_ERROR;  
  64.  
  65.   char buffer[1024];  
  66.  
  67.   memset(buffer,0,1024);  
  68.  
  69.   bytesRecv = recv( socket, buffer, 1024, 0 );  
  70.  
  71.   DWORD dwerr = WSAGetLastError();  
  72.  
  73.   CString str;  
  74.  
  75.   str.Format("%s",buffer);  
  76.  
  77.   list.InsertString(0,str);  
  78.  
  79.   ::closesocket(socket);  
  80.  
  81.   } 

#p#

  服務(wù)器端代碼,通過修改Thunderbird源代碼,使之成為一個類似HTTP服務(wù)器的服務(wù)器端

 

  1.  //***************************************************************************  
  2.  
  3.   //Author: phinecos  
  4.  
  5.   //Date : 2008/5/19  
  6.  
  7.   //Description:服務(wù)器監(jiān)聽對象  
  8.  
  9.   //Contact:phinecos@163.com  
  10.  
  11.   //***************************************************************************  
  12.  
  13.   //服務(wù)器端對象  
  14.  
  15.   const CI = Components.interfaces, CC = Components.classes, CR = Components.results;  
  16.  
  17.   var gServer = null;//服務(wù)器對象  
  18.  
  19.   var gUtility = null;//工具類對象  
  20.  
  21.   //var gConnection = null;//客戶端連接對象  
  22.  
  23.   function tBirdBiffServerOnLoad()  
  24.  
  25.   {//啟動監(jiān)聽服務(wù)器  
  26.  
  27.   try  
  28.  
  29.   {  
  30.  
  31.   gUtility = new tBirdBiffUtility();//新建日志對象  
  32.  
  33.   gUtility.initialize();  
  34.  
  35.   gUtility.log("tBirdBiffServerUi.tBirdBiffServerOnLoad", "Thunderbird biff server loaded");  
  36.  
  37.   gServer = new tBirdBiffServer();//新建服務(wù)器對象  
  38.  
  39.   gServer.initialize();//初始化服務(wù)器端  
  40.  
  41.   gUtility.log("tBirdBiffServerOnLoad","start server");  
  42.  
  43.   }  
  44.  
  45.   catch(err)  
  46.  
  47.   {  
  48.  
  49.   gUtility.log("tBirdBiffServerOnLoad","start server failed");  
  50.  
  51.   }  
  52.  
  53.   }  
  54.  
  55.   function tBirdBiffServerOnClose()  
  56.  
  57.   {//關(guān)閉服務(wù)器  
  58.  
  59.   gUtility.log("tBirdBiffServerOnClose","close server");  
  60.  
  61.   gServer.finalize();  
  62.  
  63.   gServer = null;  
  64.  
  65.   gUtility = null;  
  66.  
  67.   }  
  68.  
  69.   function tBirdBiffServer()  
  70.  
  71.   {  
  72.  
  73.   this.serverSocket = null;//服務(wù)器端socket  
  74.  
  75.   this.port = null;//服務(wù)器端口  
  76.  
  77.   this.initialized = false;  
  78.  
  79.   gUtility.log("tBirdBiffServer constructor","construct ok");  
  80.  
  81.   }  
  82.  
  83.   tBirdBiffServer.prototype =  
  84.  
  85.   {  
  86.  
  87.   getServerSocket: function()  
  88.  
  89.   {//創(chuàng)建服務(wù)器端socket  
  90.  
  91.   this.serverSocket = CC["@mozilla.org/network/server-socket;1"].createInstance(CI.nsIServerSocket);  
  92.  
  93.   if(!this.serverSocket)  
  94.  
  95.   {  
  96.  
  97.   gUtility.log("tBirdBiffServer.getServerSocket","Unable to get a server socket");  
  98.  
  99.   }  
  100.  
  101.   else  
  102.  
  103.   {  
  104.  
  105.   try  
  106.  
  107.   {  
  108.  
  109.   this.serverSocket.init(this.port, false, -1);//初始化socket,綁定到端口port上  
  110.  
  111.   this.serverSocket.asyncListen(tBirdBiffServerSocketListener);//開始異步監(jiān)聽  
  112.  
  113.   gUtility.log("tBirdBiffServer.getServerSocket","Server socket established");  
  114.  
  115.   }  
  116.  
  117.   catch(e)  
  118.  
  119.   {  
  120.  
  121.   gUtility.log("tBirdBiffServer.getServerSocket, Server socket established error");  
  122.  
  123.   this.serverSocket = null;  
  124.  
  125.   }  
  126.  
  127.   }  
  128.  
  129.   },  
  130.  
  131.   closeServerSocket: function()  
  132.  
  133.   {//關(guān)閉服務(wù)器端socket  
  134.  
  135.   if(!this.serverSocket)  
  136.  
  137.   {  
  138.  
  139.   this.serverSocket.close(null);  
  140.  
  141.   this.serverSocket = null;  
  142.  
  143.   }  
  144.  
  145.   },  
  146.  
  147.   initialize: function()  
  148.  
  149.   {  
  150.  
  151.   if(this.initialized)  
  152.  
  153.   {  
  154.  
  155.   return;  
  156.  
  157.   }  
  158.  
  159.   this.port = 25501;//獲取端口號  
  160.  
  161.   gUtility.log("tBirdBiffServer.initialize","port is: "+this.port);  
  162.  
  163.   this.getServerSocket();//創(chuàng)建服務(wù)器端socket  
  164.  
  165.   this.initialized = true;  
  166.  
  167.   gUtility.log("tBirdBiffServer.initialize","initialize ok!");  
  168.  
  169.   },  
  170.  
  171.   finalize: function()  
  172.  
  173.   {//退出程序  
  174.  
  175.   if(!this.initialized)  
  176.  
  177.   {  
  178.  
  179.   return;  
  180.  
  181.   }  
  182.  
  183.   this.closeServerSocket();//關(guān)閉服務(wù)器端socket  
  184.  
  185.   gUtility.log("tBirdBiffServer.finalize","server Finalized");  
  186.  
  187.   },  
  188.  
  189.   }  
  190.  
  191.   var listener =  
  192.  
  193.   {  
  194.  
  195.   finished : function(data)  
  196.  
  197.   {//數(shù)據(jù)讀取完畢  
  198.  
  199.   ParseCommand(data);//解析命令字  
  200.  
  201.   }  
  202.  
  203.   }  
  204.  
  205.   const tBirdBiffServerSocketListener =  
  206.  
  207.   {  
  208.  
  209.   onSocketAccepted: function(serverSocket, clientSocket)  
  210.  
  211.   {//接受來自客戶端的socket請求  
  212.  
  213.   gUtility.log("tBirdBiffServerSocketListener.onSocketAccepted","Got a connection from: " + clientSocket.host + ":" + clientSocket.port);  
  214.  
  215.   var outputData = "Ok,server get your command";  
  216.  
  217.   var outstream = clientSocket.openOutputStream(0,0,0);  
  218.  
  219.   outstream.write(outputData,outputData.length);  
  220.  
  221.   try  
  222.  
  223.   {  
  224.  
  225.   //打開輸入流  
  226.  
  227.   var stream = clientSocket.openInputStream(0,0,0);  
  228.  
  229.   var instream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);  
  230.  
  231.   instream.init(stream);  
  232.  
  233.   var dataListener =  
  234.  
  235.   {  
  236.  
  237.   data : "",//來自客戶端的數(shù)據(jù)  
  238.  
  239.   onStartRequest: function(request, context){},  
  240.  
  241.   onStopRequest: function(request, context, status){  
  242.  
  243.   instream.close();  
  244.  
  245.   outstream.close();  
  246.  
  247.   listener.finished(this.data);  
  248.  
  249.   },  
  250.  
  251.   onDataAvailable: function(request, context, inputStream, offset, count){  
  252.  
  253.   this.data += instream.read(count);  
  254.  
  255.   },  
  256.  
  257.   };  
  258.  
  259.   var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].createInstance(Components.interfaces.nsIInputStreamPump);  
  260.  
  261.   pump.init(stream, -1, -1, 0, 0, false);  
  262.  
  263.   pump.asyncRead(dataListener,null);  
  264.  
  265.   }  
  266.  
  267.   catch(err)  
  268.  
  269.   {  
  270.  
  271.   gUtility.log("tBirdBiffServerConnection.setSocket",e);  
  272.  
  273.   return false;  
  274.  
  275.   }  
  276.  
  277.   },  
  278.  
  279.   onStopListening: function(serverSocket, status)  
  280.  
  281.   {//服務(wù)器端停止監(jiān)聽  
  282.  
  283.   gUtility.log("tBirdBiffServerSocketListener.onStopListening","Server socket has stopped listening");  
  284.  
  285.   }  
  286.  
  287.   } 

【編輯推薦】

  1. Thunderbird 郵件導入導出的方法
  2. Thunderbird的安裝方法
  3. Thunderbird 配置手冊
  4. Ubuntu下安裝Thunderbird
  5. Thunderbird 的相關(guān)擴展
  6. Thunderbird中常見問題解決
  7. 圖文并茂 Thunderbird設(shè)置教程
  8. Thunderbird的使用技巧
責任編輯:zhaolei 來源: 網(wǎng)絡(luò)轉(zhuǎn)載
相關(guān)推薦

2011-01-18 17:49:29

2011-01-21 16:14:30

Thunderbird

2024-03-11 10:19:30

Plasmo瀏覽器Web

2009-06-12 14:31:59

Google WaveGoogle Wave

2011-07-21 13:30:18

Apple Safari 瀏覽器

2011-01-19 09:25:40

互聯(lián)網(wǎng)

2012-10-22 16:49:56

IBMdw

2021-05-27 14:58:07

ThunderbirdMozilla密鑰

2016-09-21 12:34:10

Chrome瀏覽器插件

2011-01-21 14:30:02

Thunderbird技巧

2011-05-12 16:30:44

Mozill應(yīng)用商店HTML5

2011-01-18 17:35:08

Thunderbird安裝方法

2011-12-07 10:03:11

Mozilla新聞

2009-07-28 17:27:26

Sun網(wǎng)絡(luò)架構(gòu)

2011-01-21 17:00:49

Thunderbird日歷

2011-01-21 15:00:08

Thunderbirdmail

2011-01-18 18:54:48

Thunderbird

2011-01-18 18:28:49

Thunderbird配置

2011-01-21 17:12:48

ThunderbirdIMAP

2011-01-21 17:22:36

Thunderbird
點贊
收藏

51CTO技術(shù)棧公眾號