Socket inheritance on different Windows platforms (150523)
The information in this article applies to:
- Microsoft Platform Software Development Kit (SDK) 1.0, when used with:
- the operating system: Microsoft Windows NT 3.51
- the operating system: Microsoft Windows NT 4.0
- the operating system: Microsoft Windows 2000
This article was previously published under Q150523 SYMPTOMSMicrosoft Windows 95 and Microsoft Windows 98 treat inheritance of Winsock
socket handles in a different manner than Microsoft Windows NT and Microsoft Windows 2000 when
using DuplicateHandle(). This article summarizes the differences.
Note In Winsock 2, WSADuplicateSocket/WSASocket is the recommended way for
sharing sockets on Windows platforms. STATUSMicrosoft has confirmed that this is a problem in the Microsoft products that are listed in the "Applies to" section.
Microsoft is researching this problem and will post more information in this article when the information becomes available.
MORE INFORMATION Under Windows NT and Windows 2000, socket handles are
inheritable by default. This feature is often used by a process that wants to
spawn a child process and have the child process interact with the remote
application on the other end of the connection. It is also common
practice on Windows NT to set the standard handles (standard input, output, or
error) of the child process to the socket handle. In such cases, the child
process usually does not know that its standard handles are actually sockets.
Windows 9 x differs from Windows NT/Windows 2000 in the following
manner: - Socket handles are not inheritable when created. To ensure
that a child process can obtain and use a socket handle created in the parent,
the handle must be explicitly duplicated using the Win32 API DuplicateHandle.
Set the bInheritHandle parameter of the API to TRUE.
- Socket handles cannot be set to the standard handles of the
child process. A programmer may use other mechanisms to pass the socket handle
to the client, such as passing the handle values as command line arguments so
that the child process can simply look at its argument vector.
Sample codeThe following sample code illustrates how to write applications
that will inherit sockets in child processes on both Windows 9x and Windows
NT/Windows 2000. Note This is 32-bit code only; 16-bit applications
cannot inherit socket handles.
// 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);
The following sample code illustrates how the newly created process
extracts the socket handle from its command line:
main(int argc, char *argv[]){
SOCKET Sock;
/* WSAStartup etc. */
if (2 == argc){
Sock = atoi(argv[1]); // use Sock
}
}
Modification Type: | Minor | Last Reviewed: | 7/11/2005 |
---|
Keywords: | kbAPI kbBug kbnetwork kbWinsock KB150523 kbAudDeveloper |
---|
|