文章編號: 150523 - 上次校閱: 2005年7月11日 - 版次: 3.3

在不同的 Windows 平台上的通訊端繼承

系統提示本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。

在此頁中

全部展開 | 全部摺疊

徵狀

Microsoft Windows 95 與 Microsoft Windows 98 對繼承的 Winsock 通訊控點端比 Microsoft Windows NT 和 Microsoft Windows 2000 的不同方式使用 DuplicateHandle() 時。本文摘要列出差異。

附註在 Winsock 2 WSADuplicateSocket/WSASocket 是建議的方法,讓共用的 Windows 平台上的通訊端。

狀況說明

Microsoft 已確認<適用於>一節所列之 Microsoft 產品確實有此問題。

Microsoft 研究這個問題,並將本文中張貼的詳細資訊,可以使用該資訊時。

其他相關資訊

在 [Windows NT 和 Windows 2000,通訊端控制代碼是可繼承預設。這項功能通常用於要繁衍 (Spawn) 子處理序,而且有子處理程序與另一端連接的遠端應用程式互動的處理程序。

它也是常見的作法,若要設定標準的 Windows NT 上控點 (標準輸入、 輸出或錯誤) 通訊端控制代碼子程序。在這種情況下子處理序通常並不知道其標準的控點是實際通訊端。

Windows 9 x 不同於 Windows NT/Windows 2000 以下列方式:
  • 通訊端控制碼不會建立時可繼承的。若要確保子處理序可以取得並使用在父代中建立的通訊端控制代碼,控點必須是明確地重複使用 Win32 API DuplicateHandle。 將 API 的 bInheritHandle 參數設定為 TRUE。
  • 通訊端控制碼不能設定為子程序的標準的控點。程式設計師可能使用其他機制來將通訊端控制代碼傳遞至用戶端例如做為命令列引數傳遞控制代碼值,使子處理序可以只是查看其引數向量。

範例程式碼

下列範例程式碼說明如何撰寫會繼承這兩個 Windows 9x 的子處理程序的通訊端的應用程式的 x 和 Windows NT/Windows 2000。

附註這是僅 32 位元程式碼 ; 16 位元應用程式不能繼承通訊端控制碼。
   // This is a Winsock server that is listening on a port.

   // When a client connects, the server spawns a child process and
   // passes the socket handle to the child.
   // The child can use this socket handle to interact with the
   // client and the parent is free to go back to waiting for
   // other clients to connect.

   OrigSock=accept(listen_socket,(struct sockaddr *)&from,&fromlen);

   if (OrigSock == INVALID_SOCKET)  {
      fprintf(stderr,"accept failed %d\n",GetLastError());
      return -1;
   }
   {
      STARTUPINFO si;
      PROCESS_INFORMATION pi;
      char argbuf[256];

      memset(&si,0,sizeof(si));

      // 
      // Duplicate the socket OrigSock to create an inheritable copy.
      // 
      if (!DuplicateHandle(GetCurrentProcess(),
            (HANDLE)OrigSock,
            GetCurrentProcess(),
            (HANDLE*)&DuplicateSock,
            0,
            TRUE, // Inheritable
            DUPLICATE_SAME_ACCESS)) {

         fprintf(stderr,"dup error %d\n",GetLastError());
         return -1;
      }
      // 
      // Spawn the child process.
      // The first command line argument (argv[1]) is the socket handle.
      // 

      wsprintf(argbuf,"child.exe %d",DuplicateSock);
      if (!CreateProcess(NULL,argbuf,NULL,NULL,
               TRUE, // inherit handles
               0,NULL,NULL,&si,&pi) ){
         fprintf(stderr,"createprocess failed %d\n",GetLastError());
         return -1;
      }

      // 
      // On Windows 95, the parent needs to wait until the child
      // is done with the duplicated handle before closing it.
      // 
      WaitForSingleObject(pi.hProcess, INFINITE);
   }
   // 

   // The duplicated socket handle must be closed by the owner
   // process--the parent. Otherwise, socket handle leakage
   // occurs. On the other hand, closing the handle prematurely
   // would make the duplicated handle invalid in the child. In this
   // sample, we use WaitForSingleObject(pi.hProcess, INFINITE) to
   // wait for the child.
   // 
   closesocket(OrigSock);
   closesocket(DuplicateSock);
				
下列的範例程式碼說明如何新建立的處理程序從其命令列中擷取通訊端控制代碼:
   main(int argc, char *argv[]){
      SOCKET Sock;

      /* WSAStartup etc. */ 
      if (2 == argc){
         Sock = atoi(argv[1]);   // use Sock
      }
   }
				

這篇文章中的資訊適用於:
  • Microsoft Platform Software Development Kit-January 2000 Edition?應用於:
    • Microsoft Windows NT 3.51 Service Pack 5
    • Microsoft Windows NT 4.0
    • Microsoft Windows 95
    • Microsoft Windows 98 Standard Edition
    • the operating system: Microsoft Windows 2000
關鍵字:?
kbmt kbapi kbbug kbnetwork kbwinsock KB150523 KbMtzh
機器翻譯機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:150523? (http://support.microsoft.com/kb/150523/en-us/ )
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。