VOID ServerTest() { // WSAStartup() is called by the system at startup and is not available in // the scripts. // The system also automatically calls WSACleanup(), so this function is // also not available to the scripts. // It should always be assumed that the system has already successfully // initialized the WinSocks DLL file. SOCKET sServer; sServer = socket( AF_INET, SOCK_STREAM, 0 ); if ( sServer == INVALID_SOCKET ) { PrintF( "Call to socket failed." ); return; } sockaddr_in saLocal; // Populate the sockaddr_in structure. saLocal.sin_family = AF_INET; // Address family. saLocal.sin_addr.S_un.S_addr = INADDR_ANY; // Wildcard IP address. saLocal.sin_port = htons( (USHORT)20248 ); // Port to use. // bind() links the socket we just created with the sockaddr_in structure. // It connects the socket with the saLocal address and a specified port. // If it returns non-zero, quit, as this indicates an error. if ( bind( sServer, &saLocal, sizeof( sockaddr_in ) ) != 0 ) { PrintF( "Call to bind failed." ); // Never leave sockets open. closesocket( sServer ); return; } // listen() instructs the socket to listen for incoming connections from // clients. The second arguement is the backlog. if( listen( sServer, 2 ) != 0 ) { closesocket( sServer ); return; } // There will also be a sClient socket. // We will set the sServer to listen for a sClient connection for 10 seconds, // then exit. SOCKET sClient; sockaddr_in saFrom; INT iFromLen = sizeof( sockaddr_in ); // This loop continuously calls accept() until it finally gets a connection, or // until 10 seconds pass. This means the incomming connection has 10 seconds // to be made. // If a connection is made, the client receives a report of its IP address and // then the connection is closed. PrintF( "Creating a saServer." ); DWORD dwTime = ProcTime(); while ( ProcTime() - dwTime < 10 * 1000 ) { CHAR szTemp[512]; // accept() will accept an incoming client connection. sClient = accept( sServer, &saFrom, &iFromLen ); if ( sClient != INVALID_SOCKET ) { SPrintF( szTemp, "Your IP is %s.\r\n", inet_ntoa( saFrom.sin_addr.S_un.S_addr ) ); // Just send this string back to the client. send( sClient, szTemp, StrLen( szTemp ), 0 ); // On our end print a message that lets us know it happened. PrintF( "Connection from %s.", inet_ntoa( saFrom.sin_addr.S_un.S_addr ) ); // And close the client socket. closesocket( sClient ); // Leave the loop after a successful connection. break; } } // Close the saServer socket. closesocket( sServer ); } BOOL DownloadFile( const CHAR * pcServer, const CHAR * pcFile, const CHAR * pcSaveTo ) { // First we have to create a socket that will be used for the connection. SOCKET sCon; sCon = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); if ( sCon == INVALID_SOCKET ) { PrintF( "Failed to create a socket." ); return FALSE; } // Now we have to resolve the host name. If we were supplied an IP instead of // a www.*.* address, we use gethostbyname(), otherwise gethostbyaddr(). UINT uiAddr; hostent * pHp; if ( inet_addr( pcServer ) == INADDR_NONE ) { pHp = gethostbyname( pcServer ); } else { uiAddr = inet_addr( pcServer ); pHp = gethostbyaddr( (CHAR *)&uiAddr, sizeof( hostent ), AF_INET ); } if ( pHp == NULL ) { // Of course it may have failed. closesocket( sCon ); PrintF( "Failed to resolve the host name." ); return FALSE; } // Now we have to make the connection using the socket from above // and the server information. sockaddr_in saServer; saServer.sin_addr.S_un.S_addr = *((DWORD *)pHp->h_addr_list[0]); saServer.sin_family = AF_INET; saServer.sin_port = htons( 80 ); if ( connect( sCon, &saServer, sizeof( sockaddr_in ) ) ) { closesocket( sCon ); PrintF( "Failed to create a connection." ); return FALSE; } // The connection has been made and we are ready to go. Create the // actual file where we are to store the download. FILE * fSaveTo = FOpen( pcSaveTo, "wb" ); if ( !fSaveTo ) { closesocket( sCon ); PrintF( "Failed to open the file to where the download will be saved." ); return FALSE; } // Create a GET command to send to the server. This tells it to start sending // the file. INT iPathLen = StrLen( pcFile ); CHAR * pcBuffer = Malloc( (iPathLen + 16) * sizeof( CHAR ) ); if ( !pcBuffer ) { FClose( fSaveTo ); closesocket( sCon ); PrintF( "Failed to create a text buffer for the command to get the file!" ); return FALSE; } SPrintF( pcBuffer, "GET %s\r\n\r\n", pcFile ); // Create the GET command. send( sCon, pcBuffer, StrLen( pcBuffer ), 0 ); // Send the command to the server. // Now our downloading loop. We just use recv() and store the data in chunks into // the file. INT iTotal = 0; INT iThis = 0; BYTE bTemp[512]; while ( (iThis = recv( sCon, bTemp, 512, 0 )) ) { FWrite( bTemp, iThis, 1, fSaveTo ); iTotal += iThis; } // Free everything. We have a socket, open file, and an allocated text buffer. Free( pcBuffer ); FClose( fSaveTo ); closesocket( sCon ); // Success! PrintF( "Downloaded %u bytes to %s.", iTotal, pcSaveTo ); // Return the size we downloaded. This might be 0 if the file size was 0. return iTotal; }