Friday, August 24, 2012

Startups for Dummies

The problem with Steve Blank’s How to Build a Web Startup (Lean Launchpad Edition) article ...

There’s little to no focus on the actual product being built.

Only 1 out of 50 points listed is actually about building a product: Its listed under step 7, which is: “Add the backend code to make the site work”.

The rest is mostly cruft and admin type work that an outsourced worker could do. No doubt its important, but 98% compared to 2%?

The article comes across as a guide to building an over-hyped marketing vehicle, solely to receive funding, rather than actually building something useful that people want to use. There’s no mention of innovation or of making people’s lives easier. This is Startups For Dummies.

Full respect to Steve Blank (a 34 year veteran of Silicon Valley) and his views, but in my view, this particular article has a glaring weakness.


Some further reading on the topic:

This Starting a Startup article by Paul Graham is simple but contains three great points he says you should focus on:
  • People/a good team
  • A product that customers want
  • Low overheads

This 12 Ways To Make Your Web Startup Investable article by StartupSmart, recommends:
  • People/a good team
  • A clear market gap (i.e. a product that customers want)
  • Timing is everything

Incidentally, Steve Blank has just announced he is giving a free online course over at Udacity - Entrepreneurship: The Lean Lanchpad (EP245). It starts on 14 September, 2012.


Follow @dodgy_coder

Subscribe to posts via RSS

Thursday, August 23, 2012

TCP/IP Sockets in .NET 4

TCP is one of the core protocols of the Internet and is a bi-directional, client/server protocol. In .NET you can use the TcpListener Class for the server component, which provides simple methods that listen for and accept incoming connection requests from clients. You can use the TcpClient Class for the client component, which provides client connections to TCP server components; it provides simple methods for connecting, sending, and receiving stream-based data over the network.

Here's a standalone C# 4.0 app that demonstrates how to setup a TCP/IP sockets based client and server in .NET. It uses a command line option to determine whether to run the client or server. There's no external files or libraries needed, just the standard ones you get with a C# 4.0 console project. I've tested it with Visual Studio 2010 in Windows, and it will also work unchanged with Mono.

To run the server, from the command prompt...
   SocketsTest -server

To run the client, from another command prompt ...
   SocketsTest -client

Below is the source code ...


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;

/// 
/// Standalone TCP/IP sockets example using C#.NET 4.0
/// 
/// 
/// Compile as a C#.NET console mode application
/// 
/// Command line usage:
///   SocketsTest -client   => run the client
///   SocketsTest -server   => run the server
/// 
class SocketsTest
{
    static TcpListener listener;

    // Sample high score table data
    static Dictionary<string, int> highScoreTable = new Dictionary<string, int>() { 
            { "john", 1001 }, 
            { "ann", 1350 }, 
            { "bob", 1200 }, 
            { "roxy", 1199 } 
    };

    static int Port = 4321;
    static IPAddress IP_ADDRESS = new IPAddress(new byte[] { 127, 0, 0, 1 });
    static string HOSTNAME = "127.0.0.1";
    static int MAX_CLIENTS = 5;

    public static void Main(string[] args)
    {
        if (args.Contains("-server"))
        {
            ServerMain();
        }
        else if (args.Contains("-client"))
        {
            ClientMain();
        }
        else
        {
            Console.WriteLine("Usage: SocketsTest -client   => run the client");
            Console.WriteLine("       SocketsTest -server   => run the server");
        }
    }

    /// 
    /// Server receives player name requests from the client and responds with the score.
    /// 
    private static void ServerMain()
    {
        listener = new TcpListener(IP_ADDRESS, Port);
        listener.Start();
        Console.WriteLine("Server running, listening to port " + Port + " at " + IP_ADDRESS);
        Console.WriteLine("Hit Ctrl-C to exit");
        var tasks = new List();
        for (int i = 0; i < MAX_CLIENTS; i++)
        {
            Task task = new Task(Service, TaskCreationOptions.LongRunning);
            task.Start();
            tasks.Add(task);
        }
        Task.WaitAll(tasks.ToArray());
        listener.Stop();
    }

    private static void Service()
    {
        while (true)
        {
            Socket socket = listener.AcceptSocket();

            Console.WriteLine("Connected: {0}", socket.RemoteEndPoint);
            try
            {
                // Open the stream
                Stream stream = new NetworkStream(socket);
                StreamReader sr = new StreamReader(stream);
                StreamWriter sw = new StreamWriter(stream);
                sw.AutoFlush = true;

                sw.WriteLine("{0} stats available", highScoreTable.Count);
                while (true)
                {
                    // Read name from client
                    string name = sr.ReadLine();
                    if (name == "" || name == null) break;

                    // Write score to client
                    if (highScoreTable.ContainsKey(name))
                        sw.WriteLine(highScoreTable[name]);
                    else
                        sw.WriteLine("Player '" + name + "' was not found.");

                }
                stream.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.WriteLine("Disconnected: {0}", socket.RemoteEndPoint);
            socket.Close();
        }
    }

    /// 
    /// Client requests a player name's score from the server.
    /// 
    private static void ClientMain()
    {
        TcpClient client = new TcpClient(HOSTNAME, Port);
        try
        {
            // Open the stream
            Stream stream = client.GetStream();
            StreamReader sr = new StreamReader(stream);
            StreamWriter sw = new StreamWriter(stream);
            sw.AutoFlush = true;

            // Read and output the first line from the service, which
            // contains the number of players listed in the table.
            Console.WriteLine(sr.ReadLine());

            while (true)
            {
                // Input player name
                Console.Write("Enter player name: ");
                string name = Console.ReadLine();

                // Write name to server
                sw.WriteLine(name);
                if (name == "") break;

                // Read score from server
                Console.WriteLine(sr.ReadLine());
            }
            stream.Close();
        }
        finally
        {
            // Close the connection
            client.Close();
        }
    }
}




Follow @dodgy_coder

Subscribe to posts via RSS

Saturday, August 11, 2012

EMPORI: The original Amazon Locker from 12 years ago


Amazon Locker is a new delivery option offered by Amazon which provides secure, self-service pick-up stations located in a select number of cities in the US and UK. Once your package is delivered to the Amazon Locker, you receive an e-mail informing you that your package is available for pick-up.

This Amazon service came about 1 year after a Canadian startup called BufferBox started offering a similar secure dropbox service. BufferBox has lockers installed in two locations in Waterloo, one at the university and another a nearby corporate office. The company is nearing a launch in Toronto and plans to roll out lockers across Canadian and U.S. cities.

But back in 2000, another Canadian company launched a similar service. On July 24, 2000, Canadian property management company Oxford Properties Group launched a startup called EMPORI.COM. Customers could order products from affiliated online retailers via  Empori.com, which were then delivered on the same or next day to a secure depot containing lockers. The original depot was located in an office building in Toronto (Royal Bank Plaza) and over the course of a year this expanded to three more sites around Toronto. Oxford Properties Group saw this as a way for their commercial real estate customers to get additional value out of their prime inner city locations. The idea was that city workers would order products online and then, after receiving an email notification with the locker location and locker combination, would pick their order up at the end of the day, on their way home from work. A host of a products from 31 vendors were offered, from books to running shoes to groceries and even liquor.

The upmarket secure lockers offered by Empori
From the launch press release: "Empori.com is the one-of-a-kind retail solution to those barriers that discourage people from purchasing online. Our delivery system addresses the online shopping fulfillment problem."

Less than 1 year later, on July 17, 2001,  Empori.com closed after a $5 million loss. The blame was initially placed on the general business environment which included the bursting of the dot com bubble: "With recent changes in the dot-com environment, [Empori] was unable to find another strategic and financial partner to support further development of the business-to-consumer business,"

As the dust settled it looked like the single biggest factor in Empori’s failure was its inability to secure a critical mass of online retailers.  They tried to do too much - secure depots for pick-up was only one piece of their ambitious plan - they were also reselling goods via their website, which was the sole point of contact to access their secure depots. In effect they were trying to launch a new online retail site, coming off a base of zero customers, while in the general dot com gloom of 2000/01. Maybe what they should have done is to focus solely on their unique selling point - the secure depot - and offered it as a service, available to any online retailer, much as BufferBox is doing today.

The business burned $5 million in one year before closing
As of today, the Empori.com domain name is offered for outright sale for 3540 ($4351) by a European domain reseller. "Empori" is Italian for "Stores".