gethostbyname

•July 19, 2012 • Leave a Comment

gethostbyname() is a socket library function that looks up the IPV4 address of a computer from it’s name.

Every now and then someone asks how to call gethostbyname().  The description is here: http://pubs.opengroup.org/onlinepubs/007908799/xns/gethostname.html

Here’s an example.

#ifdef _WIN32
	#include <WinSock2.h>
	#include <WS2tcpip.h>
	typedef unsigned uint32_t;
#else
	#include <netdb.h>
	#include <arpa/inet.h>
	#include <netinet/in.h>
	#include <sys/socket.h>  // BSD needs this
#endif

#include <iostream>
#include <string>
#include <stdexcept>
#include <vector>

typedef std::vector<std::string> strings_t;

strings_t getip(std::string hostname) 
{
	if (struct hostent* hent = gethostbyname(hostname.c_str()))
	{
		if (hent->h_addrtype == AF_INET  &&  hent->h_length == sizeof(uint32_t))
		{
			strings_t hosts;

			for (int i = 0; hent->h_addr_list[i]; ++i)
			{
				struct in_addr addr = { 0 };
				addr.s_addr = *(uint32_t*)hent->h_addr_list[i];
				hosts.push_back(inet_ntoa(addr));
			}
			return hosts;
		}

		std::string text = "cannot find ip4 address for host:" + hostname;
		throw std::runtime_error(text);
	}

	std::string text = "cannot find ip address for host:" + hostname;
	throw std::runtime_error(text);
}

int main()
{
#ifdef _WIN32
	WSADATA wsadata = { 0 };
	WSAStartup(MAKEWORD(2, 2), &wsadata);
#endif

	std::string line;
	while (std::cin >> line)
	{
		try
		{
			strings_t hosts = getip(line);
			for (strings_t::const_iterator p = hosts.begin(); p != hosts.end(); ++p)
				std::cout << *p << std::endl;
		}
		catch (const std::exception &e)
		{
			std::clog << e.what() << std::endl;
		}
	}

	return 0;
}
Advertisements

π in C++

•July 19, 2012 • Leave a Comment

Recently I’ve helped out with a couple of queries about calculating PI.  They’re programming assingments for students rather than real mathematical problems. I thought I’d publish them here.

The Monte Carlo Method

The idea is to use a game of chance to esitmate a value for PI.

You start by drawing a square of length 1 with a quarter of a circle of radius 1 inside the square.

If you were to throw a dart randomly at this shape, what are the chances of it landing inside the quarter circle?

The answer is (area of quarter circle) / (area of square). As the area of a square of length 1 is 1, the chance becomes (area of quarter circle) which is (PI * radius squared / 4). And as the radius of 1 squared is still 1, the answer is PI/4.

So the chance of your dart landing in the quarter circle is PI/4.

If we do this once, we’ll get a value of 0 or 4 for PI. But as we do it more and more, we get better approximations for PI.

You could ask 3 friends to help you do this test be throwing darts and checking how many were in the quarter circle for a fixed number of throws. At the end, you’d find the ratio of how many were in, then multiply that by 4 and get a value for PI.

Back to the computer program. We throw the dart by getting random (x,y) coordinates. We know it’s in the circle if the distance from the origin (0,0) is less than or equal to 1. And we calculate the distance using Pythagoras’ theorem, c2 = a2 + b2. But as 12 is still 1, we can just work with c2 and not attempt the square root.

Each thread does the same test and you just check the results at the end.

#include <pthread.h>
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <stdint.h>
namespace MonteCarloPI
{
    struct Info
    {
        typedef uint32_t value_type;

        Info() : inPoints(0), totalPoints(0) {}

        value_type inPoints;
        value_type totalPoints;
    };

    void* func(void* param)
    {
        if (Info* info = reinterpret_cast<Info*>(param))
        {
            // do some work
            for (size_t i = 0; i != info->totalPoints; ++i)
            {
                std::pair<double, double> pt(rand()/(double)RAND_MAX, rand()/(double)RAND_MAX);
                double d = pt.first*pt.first + pt.second*pt.second;
                if (d <= 1.0) 
                    ++(info->inPoints); 
            } 
        }

        return param;
    }

    double pi(size_t nthreads, size_t niters)
    {
        std::vector<pthread_t> handles(nthreads);
        std::vector<Info> info(nthreads);

        // start the threads
        for (size_t i = 0; i != nthreads; ++i)
        {
            info[i].totalPoints = niters;
            pthread_create(&handles[i], NULL, func, &info[i]);
        }

        // wait for the threads to complete
        for (size_t i = 0; i != nthreads; ++i)
            pthread_join(handles[i], NULL);

        // process the reply
        double inPoints = 0.0;
        double totalPoints = 0.0;
        for (size_t i = 0; i != nthreads; ++i)
        {
            inPoints += info[i].inPoints;
            totalPoints += info[i].totalPoints;
        }
        const double pi = (4.0 * inPoints / totalPoints);

        return pi;
    }
}

int main()
{
    srand(2012);

    const size_t NTHREADS = 4;
    const size_t NITERS = 100*1000*1000;

    double pi = MonteCarloPI::pi(NTHREADS, NITERS);
    std::cout << "pi = " << pi << std::endl;

    return 0;
}

Leibniz Method

It’s probably best to start with a description of the algorithm. http://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80

#include <iostream>
#include <stdlib.h>
#include <stdint.h>
namespace LiebnizPI
{
    typedef uint32_t value_type;

    double pi(value_type niters)
    {
        double pi = 0.0;
        for (size_t i = 0; i != niters; ++i)
        {
            if (i % 2)
                pi -= 1.0 / (2*i + 1);
            else
                pi += 1.0 / (2*i + 1);
        }

        return 4.0 * pi;
    }
}

int main()
{
    srand(2012);

    const LiebnizPI::value_type NITERS = 1*1000*1000;

    double pi = LiebnizPI::pi(NITERS);
    std::cout << "pi = " << pi << std::endl;

    return 0;
}

Building Wireshark 1.4.3 for 32-bit Windows

•January 30, 2011 • Leave a Comment

Why bother to write a log about building Wireshark?  Because the standard build does not work.  This log describes how to work around the defects and build wireshark with various versions of Microsoft Visual Studio.

Microsoft Visual Studio 6 cannot be used.  epan, The Ethernet Protocol Analyser, does not build under Visual Studio 6.  As far as I can tell, there’s no good reason for this.  The problems lie in the syntax of 64 bit int supprt.

Wireshark creates a a directory, C:\wireshark-win32-libs-1.4.  This directory hold wireshark versions of 3rd party libraries used in the build.  GeoIP is broken.

The current cygpath (part of cygwin) is broken.  If you find it causes your build to fail, edit tools/win-setup.sh and change calls to cygpath –dos to cygpath –windows.

Install Cygwin. You’ll need the following packages.

  • base/tar
  • archive/unzip
  • devel/bison
  • devel/flex
  • interpreters/perl
  • utils/patch
  • web/wget

Download Python.  My version is 2.7.

Download wireshark-1.4.3.tar.bz2

Edit wireshark-1.4.3/config.nmake

  • Enable Python removing comments from the two lines PYTHON_VER and PYTHON_DIR
  • Set PYTHON_VER=27
  • Comment the line starting GEOIP_DIR
  • Note that some known broken packages are already commented out, like PCRE
  • Set the appropriate Visual Studio version with: MSVC2005, MSVC2008, MSVC2010.
  • I have confirms that Visual Stdio Version 2005, 2008 and 2010 build wireshark.

Change directory to wireshark-1.4.3 and run:

  • nmake -f Makefile.nmake setup
  • nmake -f Makefile.nmake all

C Time Times

•October 25, 2010 • Leave a Comment
Location Type Functions Resolution
ANSI Time time_t time second
stat/fstat
difftime
mktime
ctime
struct tm gmtime second
localtime
asctime
strftime
Old Unix File Time struct timeb ftime millisecond
New Unix Time struct timeval gettimeofday microsecond
select
utimes
Windows System File Time SYSTEMTIME GetSystemTime millisecond
SetSystemTime
GetLocalTime
SetLocalTime
SystemTimeToFileTime
FileTimeToSystemTime
Windows File Time FILETIME GetSystemTimeAsFileTime 100 nanoseconds
SystemTimeToFileTime
FileTimeToSystemTime
FileTimeToLocalFileTime
LocalFileTimeToFileTime
CompareFileTime
FileTimeToDosDateTime
DosDateTimeToFileTime
Windows Performance Time LARGE_INTEGER QueryPerformanceTime 10 nanoseconds
QueryPerformanceTimeFrequency

Hello world!

•October 25, 2010 • 1 Comment

Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!