This one was getting me for a while too. To connect to an arbitrary client you must bind the socket to either socket.gethostname() which is what I'm using with success. or use empty string "" In reference to the server code: A couple things to notice: we used socket.gethostname() so that the socket would be visible to the outside world. If we had used s.bind(('localhost', 80)) or s.bind(('127.0.0.1', 80)) we would still have a "server" socket, but one that was only visible within the same machine. s.bind(('', 80)) specifies that the socket is reachable by any address the machine happens to have.