Platform SDK: Active Directory, ADSI, and Directory Services |
The following program implements the example Winsock service with RnR publication.
This sample calls the serverRegister and serverUnregister sample routines, which are documented in the Example Code for Publishing the RnR Connection Point section.
/* ** Simple Winsock Server */ #include <winsock2.h> #include <stdio.h> INT serverRegister(SOCKADDR *); INT serverUnregister(SOCKADDR *); HRESULT main(void) { //Data structures for initializing Winsock. WSADATA wsData; WORD wVer = MAKEWORD(2,2); //Data structures for setting up communications. SOCKET s, newsock; SOCKADDR sa; struct hostent *he; char szName[255]; struct sockaddr_in sa_in; INT ilen; ULONG icmd; ULONG ulLen; //Miscellaneous variables INT status; WCHAR wszRecvBuf[100]; memset(wszRecvBuf,0,sizeof(wszRecvBuf)); //Begin: Init Winsock2 status = WSAStartup(wVer,&wsData); if (status != NO_ERROR) return -1; //Create the socket. s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if (s == INVALID_SOCKET) { printf("Failed to create socket: %d\n",WSAGetLastError()); WSACleanup(); return -1; } //Disable non-blocking IO for purposes of this example. icmd = 0; status = ioctlsocket(s,FIONBIO,&icmd); //Bind the socket to a dynamically assigned port. sa.sa_family=AF_INET; memset(sa.sa_data,0,sizeof(sa.sa_data)); status = bind(s,&sa,sizeof(sa)); //Note that we need to convert the port to the local //host byte order. ilen = sizeof(sa_in); status = getsockname(s,(struct sockaddr *)&sa_in,&ilen); if (status == NO_ERROR) { printf("Server: Bound to port %d\n",ntohs(sa_in.sin_port)); } //Figure out our net address to fill in for registering ourselves //in the directory service. Explicitly call the ANSI text version //because gethostbyname does not understand UNICODE. ilen = sizeof(szName); GetComputerNameA(szName,&ulLen); he = gethostbyname(szName); //Put the address in the SOCKADDR struct. This is not //as difficult as it looks. sa_in.sin_addr.S_un.S_addr = *((long *)(he->h_addr)); //Listen for connections. SOMAXCONN tells the provider to queue //a "reasonable" number of connections. status = listen(s,SOMAXCONN); if (status != NO_ERROR) { printf("Failed to set socket listening: %d\n", WSAGetLastError()); WSACleanup(); return -1; } //Register this instance with RnR. status = serverRegister((SOCKADDR *)&sa_in); if (status != NO_ERROR) { printf("Failed to register instance: %d\n",WSAGetLastError()); WSACleanup(); return -1; } printf("Server: Registered instance in the directory service\n"); //Block waiting for a connection. This example is single-threaded //for simplicity. In a real service, spin off //one or more threads here to call AcceptEx here and process the //connections through a completion port. ilen = sizeof(sa); newsock = accept(s,&sa,&ilen); if (newsock == INVALID_SOCKET) { printf("Failed to create socket: %d\n",WSAGetLastError()); status = serverUnregister((SOCKADDR *)&sa_in); WSACleanup(); return -1; } printf("Server: There is a client connection\n"); //Receive a message from the client and shut down. status = recv(newsock,(char *)wszRecvBuf,sizeof(wszRecvBuf),0); if (status > 0) printf("Server: Received: %S\n",wszRecvBuf); //Unregister ourselves printf("Unregistering and shutting down.\n"); status = serverUnregister((SOCKADDR *)&sa_in); WSACleanup(); return 0; }