<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>A Tasty Pixel » Blog &#187; Software</title>
	<atom:link href="http://atastypixel.com/blog/tag/software/feed/" rel="self" type="application/rss+xml" />
	<link>http://atastypixel.com/blog</link>
	<description></description>
	<lastBuildDate>Mon, 06 Feb 2012 15:08:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Sparrow users beware: Bug sends prior draft instead of latest email version</title>
		<link>http://atastypixel.com/blog/sparrow-users-beware-bug-sends-prior-draft-instead-of-latest-email-version/</link>
		<comments>http://atastypixel.com/blog/sparrow-users-beware-bug-sends-prior-draft-instead-of-latest-email-version/#comments</comments>
		<pubDate>Thu, 18 Aug 2011 19:41:50 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Geekspeak]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Email]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Sparrow]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/?p=2243</guid>
		<description><![CDATA[Update: The Sparrow guys tell me they&#8217;ve found and nailed the bug, and will release the fix in 1.4 in late September. I&#8217;ve just discovered a critical issue with Sparrow that I thought others should be warned of. It just bit me, big-time, when in the middle of an important negotiation with a third party, [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update</strong>: <em>The Sparrow guys tell me they&#8217;ve found and nailed the bug, and will release the fix in 1.4 in late September.</em></p>

<p>I&#8217;ve just discovered a critical issue with Sparrow that I thought others should be warned of.  It just bit me, big-time, when in the middle of an important negotiation with a third party, an earlier unpolished draft was sent out instead of the final email, when I experienced a momentary Internet connection dropout.</p>

<p>Sparrow has an issue where hitting &#8220;Send&#8221;, in unreliable network conditions, on a draft message that has been modified, results in a prior copy of the message being sent, rather than the latest version.</p>

<p>To replicate this issue reliably:</p>

<ol>
<li>Create a new message (Cmd-N)</li>
<li>Specify a recipient (oneself), subject, and some body content (say, the letter &#8220;A&#8221;)</li>
<li>Hit &#8220;Save&#8221;, to save the draft</li>
<li>Change &#8220;A&#8221; to &#8220;B&#8221;, then disconnect the network connection (in my case, turning off the radio on my external WiFi adapter), then hit &#8220;Send&#8221;.  Sparrow will report a failed connection, and will keep the outgoing message with state &#8220;Pending&#8221;</li>
<li>Restore network connection.  Upon detecting the restored connection, Sparrow will proceed to send the message</li>
<li>Check email. Received test email will have &#8220;A&#8221; in the email body.</li>
</ol>

<p>Scary stuff.  I hope they&#8217;ll fix this soon, but it&#8217;s going to make the app difficult to trust in future!</p>

<p><strong>Update</strong>: I should mention, a probable workaround for this is to never, ever hit &#8220;Send&#8221; until you&#8217;ve saved the draft, and verified that the save operation has completed (perhaps even restart the app first).</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=2243" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/sparrow-users-beware-bug-sends-prior-draft-instead-of-latest-email-version/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Loopy 2 launch &#8211; now with real fruit pieces</title>
		<link>http://atastypixel.com/blog/loopy-2-launch-now-with-real-fruit-pieces/</link>
		<comments>http://atastypixel.com/blog/loopy-2-launch-now-with-real-fruit-pieces/#comments</comments>
		<pubDate>Thu, 16 Jun 2011 10:59:44 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Products]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Loopy]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/loopy-2-launch-now-with-real-fruit-pieces/</guid>
		<description><![CDATA[I&#8217;m very pleased to announce the launch of our new app, Loopy 2! It&#8217;s a pretty, easy-to-use but feature-packed looper for making music by layering looped recordings of singing, beatboxing or playing an instrument (or banging cutlery together). It&#8217;s currently on sale for launch, so take a look! We&#8217;re very proud of it.]]></description>
			<content:encoded><![CDATA[<p><a href="http://loopyapp.com"><img src="http://atastypixel.com/products/loopy/press/screenshots/Screens.jpg" width="400" height="410" alt="Loopy 2" class="alignright" /></a>
I&#8217;m very pleased to announce the launch of our new app, <a href="http://loopyapp.com">Loopy 2</a>! It&#8217;s a pretty, easy-to-use but feature-packed looper for making music by layering looped recordings of singing, beatboxing or playing an instrument (or banging cutlery together).</p>

<p>It&#8217;s currently on sale for launch, so take a look! We&#8217;re very proud of it.</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=2197" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/loopy-2-launch-now-with-real-fruit-pieces/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Post Grabber sniffs out POST data, generates curl scripts</title>
		<link>http://atastypixel.com/blog/post-grabber-sniffs-out-post-data-generates-curl-scripts/</link>
		<comments>http://atastypixel.com/blog/post-grabber-sniffs-out-post-data-generates-curl-scripts/#comments</comments>
		<pubDate>Thu, 21 Apr 2011 08:59:04 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Geekspeak]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Utility]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/post-grabber-sniffs-out-post-data-generates-curl-scripts/</guid>
		<description><![CDATA[Every now and then I find myself needing to automate some web requests, either to download using something a little more robust than a web browser, scrape some web content, or to maintain a session. That automation can be a bit of a pain if there&#8217;s a form submission involved, because it means opening up [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://atastypixel.com/blog/wp-content/uploads/2011/04/michaeltyson_PostGrabber_raw_master_screenshot.png" width="300" height="294" alt="Post Grabber screenshot" class="alignright" />Every now and then I find myself needing to automate some web requests, either to download using something a little more robust than a web browser, scrape some web content, or to maintain a session.  That automation can be a bit of a pain if there&#8217;s a form submission involved, because it means opening up the page source, finding the form and any connected javascript code, and figuring out what fields are submitted.</p>

<p>A little utility I just put together does that for you: <a href="https://github.com/michaeltyson/PostGrabber">Post Grabber</a> detects POST data and generates an equivalent &#8220;curl&#8221; command that can be used in shell or Automator scripts.</p>

<p>Post Grabber works with its own internal browser, so it can intercept POST submissions directly. That means it works with HTTPS, unlike the traditional web sniffer approach.</p>

<p><a href="https://github.com/downloads/michaeltyson/PostGrabber/Post%20Grabber%201.2.zip">Download the app</a>, or see the <a href="https://github.com/michaeltyson/PostGrabber">source on GitHub</a>.</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=2189" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/post-grabber-sniffs-out-post-data-generates-curl-scripts/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Internet Timer keeps track of your timed Internet usage</title>
		<link>http://atastypixel.com/blog/internet-timer-keeps-track-of-your-timed-internet-usage/</link>
		<comments>http://atastypixel.com/blog/internet-timer-keeps-track-of-your-timed-internet-usage/#comments</comments>
		<pubDate>Sun, 13 Mar 2011 17:40:02 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Geekspeak]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/internet-timer-keeps-track-of-your-timed-internet-usage/</guid>
		<description><![CDATA[I threw this utility app together last year, in order to keep track of our Internet usage on a time-limited account. This is a piece of software that lives quietly in your menubar, until an Internet connection is detected. Then, it will count how long you&#8217;ve been online, showing a timer in the menubar. Features: [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://atastypixel.com/blog/wp-content/uploads/2011/03/internet-timer-icon.png" width="200" height="200" alt="Internet Timer icon" class="alignright" />I threw this utility app together last year, in order to keep track of our Internet usage on a time-limited account.  This is a piece of software that lives quietly in your menubar, until an Internet connection is detected.  Then, it will count how long you&#8217;ve been online, showing a timer in the menubar.</p>

<p>Features:</p>

<ul>
<li>Detects your Internet connection automatically, or you can start and stop the timer manually.</li>
<li>Keep a log of your usage, including weekly, monthly, and all-time totals, and daily average, with the ability to reset these.</li>
<li>Time in configurable blocks of time, if your carrier charges in blocks (e.g., 15 minutes)<span id="more-2161"></span><img src="http://atastypixel.com/blog/wp-content/uploads/2011/03/internet-timer-screenshot.png" width="254" height="168" alt="Internet timer screenshot: Menubar" class="aligncenter" style="margin-top: 30px;" /></li>
</ul>

<p><img src="http://atastypixel.com/blog/wp-content/uploads/2011/03/internet-timer-screenshot-2.png" width="400" height="374" alt="Internet Timer screenshot: Statistics viewer" class="aligncenter" /></p>

<p>Grab it here:</p>

<p><center><a href="http://atastypixel.com/blog/wp-content/uploads/2011/03/Internet-Timer.zip" title="Internet Timer.zip" style="text-decoration: none; font-size: 2.0em; color: black;"><img src="http://atastypixel.com/blog/wp-content/uploads/2011/03/internet-timer-icon-small.png" width="48" height="48" alt="internet-timer-icon-small.png" style="vertical-align: middle;" /> Internet Timer</a></center></p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=2161" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/internet-timer-keeps-track-of-your-timed-internet-usage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Announcing The Cartographer 1.1, with Offline Map Downloading, Map Search, and Bulk Publishing</title>
		<link>http://atastypixel.com/blog/announcing-the-cartographer-1-1-with-offline-map-downloading-map-search-and-bulk-publishing/</link>
		<comments>http://atastypixel.com/blog/announcing-the-cartographer-1-1-with-offline-map-downloading-map-search-and-bulk-publishing/#comments</comments>
		<pubDate>Thu, 16 Dec 2010 16:14:02 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Products]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[The Cartographer]]></category>
		<category><![CDATA[Update]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/?p=2095</guid>
		<description><![CDATA[We&#8217;ve just released The Cartographer version 1.1! New features include: Bulk-download offline maps View placemarks in a list, mass-publish placemarks, and search placemarks Search the map for street names, towns, landmarks and more Our biggest and most-requested new feature is offline map downloading &#8212; now, you can select a whole map region to download, and [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve just released <a href="http://cartographer-app.com">The Cartographer</a> version 1.1!</p>

<p>New features include:</p>

<ul>
<li>Bulk-download offline maps</li>
<li>View placemarks in a list, mass-publish placemarks, and search placemarks</li>
<li>Search the map for street names, towns, landmarks and more</li>
</ul>

<p><img src="http://atastypixel.com/blog/wp-content/uploads/2010/12/cartographer-1-1.jpg" width="286" height="300" alt="The Cartographer Version 1.1 with Offline Map Downloading and List View" class="alignright" />
Our biggest and most-requested new feature is offline map downloading &#8212; now, you can select a whole map region to download, and a level of detail, and The Cartographer will download the entire street map to your iPhone, for viewing offline.  <a href="http://www.youtube.com/watch?v=aK88V0gme5g">This video</a> shows how it works.</p>

<p>The second main new feature is map searching, so you can search for places by name.  A tap converts search results to placemarks you can add to your map.</p>

<p>Bulk placemark publishing lets you make lots of placemarks while you&#8217;re away from Internet access, and then when you have Internet access, publish them to your map all at once.</p>

<p>And finally, a new list view shows you all placemarks on your map, ordered by how far away they are.  You can also search your placemarks by their name or description.</p>

<p>We hope you like The Cartographer 1.1!  We sure do.</p>

<p>Grab it on the <a href="http://itunes.apple.com/app/the-cartographer/id393312081?mt=8">iPhone App Store</a> for $3.99.</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=2095" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/announcing-the-cartographer-1-1-with-offline-map-downloading-map-search-and-bulk-publishing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Coming soon: Bulk downloading of offline maps</title>
		<link>http://atastypixel.com/blog/coming-soon-bulk-downloading-of-offline-maps/</link>
		<comments>http://atastypixel.com/blog/coming-soon-bulk-downloading-of-offline-maps/#comments</comments>
		<pubDate>Mon, 06 Dec 2010 13:52:17 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Products]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[The Cartographer]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/coming-soon-bulk-downloading-of-offline-maps/</guid>
		<description><![CDATA[Here&#8217;s something I&#8217;ve just finished working on, ready for release very soon: Offline map downloading. You can grab The Cartographer on the iPhone App Store &#8212; version 1.1 will be available shortly, and is a free update. When we release version 1.1, we&#8217;ll be ending our introductory 50% off sale, so grab a copy soon [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s something I&#8217;ve just finished working on, ready for release very soon: Offline map downloading.</p>

<p><object width="560" height="340" class="aligncenter"><param name="movie" value="http://www.youtube.com/v/aK88V0gme5g?fs=1&amp;hl=en_GB"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/aK88V0gme5g?fs=1&amp;hl=en_GB" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object></p>

<p>You can grab <a href="http://itunes.apple.com/app/the-cartographer/id393312081?mt=8">The Cartographer on the iPhone App Store</a> &#8212; version 1.1 will be available shortly, and is a free update.  When we release version 1.1, we&#8217;ll be ending our introductory 50% off sale, so grab a copy soon before the price goes up!</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=2090" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/coming-soon-bulk-downloading-of-offline-maps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Software Should Be Beautiful</title>
		<link>http://atastypixel.com/blog/software-should-be-beautiful/</link>
		<comments>http://atastypixel.com/blog/software-should-be-beautiful/#comments</comments>
		<pubDate>Mon, 15 Nov 2010 11:22:34 +0000</pubDate>
		<dc:creator>katherine</dc:creator>
				<category><![CDATA[Products]]></category>
		<category><![CDATA[Maps]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[The Cartographer]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/software-should-be-beautiful/</guid>
		<description><![CDATA[Software should be beautiful, and should be a pleasure to use. The Cartographer combines antique cartography styling with cutting edge technology. On the iPhone 4’s Retina display, The Cartographer flaunts stunning high-resolution graphics. Win 1 of 15 Free Copies of The Cartographer Subscribe to our newsletter to stay up to date and for a chance [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://atastypixel.com/blog/wp-content/uploads/2010/11/The-Cartographer-iPhone-App-Sneak-peek1.jpg" width="570" height="220" alt="The Cartographer iPhone App Sneak-peek.jpg" class="aligncenter" /></p>

<p>Software should be beautiful, and should be a pleasure to use. The Cartographer combines antique cartography styling with cutting edge technology. On the iPhone 4’s Retina display, The Cartographer flaunts stunning high-resolution graphics.</p>

<h3>Win 1 of 15 Free Copies of The Cartographer</h3>

<p><a href="http://atastypixel.com/newsletter/">Subscribe to our newsletter</a> to stay up to date and for a chance of winning one of fifteen promo codes.</p>

<h3>Win Chris Guillebeau&#8217;s &#8220;Travel Master Kit&#8221;</h3>

<ol>
<li><a href="http://twitter.com/ATastyPixel">Follow @ATastyPixel</a> on Twitter.</li>
<li><a href="http://twitter.com/home?status=Win+Chris+Guillebeau%27s+%22Travel+Master+Kit+for+the+launch+of+%40ATastyPixel%27s+The+Cartographer+http%3A%2F%2Fcartographer-app.com">Tweet this</a>: Win Chris Guillebeau&#8217;s &#8220;Travel Master Kit&#8221;  for the launch of @ATastyPixel&#8217;s The Cartographer <a href="http://cartographer-app.com">http://cartographer-app.com</a></li>
</ol>

<p>The Contest ends November 25th, 2010 at midnight GMT. The winner will be notified via direct message on Twitter.</p>

<p>There is no restriction to the number of entries so tweet your little hearts out!</p>

<p>Chris Guillebeau’s “Travel Master Kit” includes three e-books &#8211; “Frequent Flyer Master”, the “Discount Airfare Guide&#8221;, and “Travel Ninja”, complete with bonuses.  <a href="http://cartographer-app.com">Read more</a>.</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=2050" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/software-should-be-beautiful/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Reginald RegEx explorer</title>
		<link>http://atastypixel.com/blog/reginald-regex-explorer/</link>
		<comments>http://atastypixel.com/blog/reginald-regex-explorer/#comments</comments>
		<pubDate>Sat, 31 Jul 2010 22:28:27 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Geekspeak]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Regex]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/reginald-regex-explorer/</guid>
		<description><![CDATA[With a desperate need to debug a lengthy regular expression destined for use with the excellent RegexKitLite library, I have quickly put together a Mac OS X application. Reginald is a kindly old gentleman devoted to assisting you with those tricky regular expressions. Provide some sample input, and your regular expression, and Reginald will provide [...]]]></description>
			<content:encoded><![CDATA[<p>With a desperate need to debug a lengthy regular expression destined for use with the excellent <a href="http://regexkit.sourceforge.net/RegexKitLite/">RegexKitLite</a> library, I have quickly put together a Mac OS X application.</p>

<p><img src="http://atastypixel.com/blog/wp-content/uploads/2010/07/reg.png" width="64" height="69" alt="Reginald icon" style="float:right;" />
Reginald is a kindly old gentleman devoted to assisting you with those tricky regular expressions.</p>

<p>Provide some sample input, and your regular expression, and Reginald will provide you with colour-coded output and a list of all your matches and the corresponding capture groups for your exploration.  Select a match or capture group in the list to the right, and the corresponding text will be selected in the panel to the left.</p>

<p>Reginald is built on <a href="http://regexkit.sourceforge.net/RegexKitLite/">RegexKitLite</a>, and so uses the <a href="http://regexkit.sourceforge.net/RegexKitLite/index.html#ICUSyntax">ICU syntax</a>.</p>

<p>It will run on Mac OS X 10.6 and above.</p>

<p><a href="http://github.com/michaeltyson/Reginald/downloads">Download Reginald here</a>, or <a href="http://github.com/michaeltyson/Reginald">access the source on GitHub</a>.</p>

<p><a href="http://atastypixel.com/blog/wp-content/uploads/2010/07/201007312318.jpg" rel="lightbox[1966]"><img src="http://atastypixel.com/blog/wp-content/uploads/2010/07/201007312318-tm.jpg" width="450" height="342" alt="Reginald screenshot" class="aligncenter" /></a></p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1966" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/reginald-regex-explorer/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Loopy is on sale</title>
		<link>http://atastypixel.com/blog/loopy-is-on-sale/</link>
		<comments>http://atastypixel.com/blog/loopy-is-on-sale/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 12:56:42 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Products]]></category>
		<category><![CDATA[Loopy]]></category>
		<category><![CDATA[Sale]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/loopy-is-on-sale/</guid>
		<description><![CDATA[Loopy, my loop-based musical instrument and musical notepad app, is going on sale in anticipation of Loopy 2, which is on its way, with a release expected a little later this year. Here&#8217;s some recent feedback on Loopy (about which I&#8217;m thrilled!): Loopy does more of what I wanted than my Boss looper pedal that [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://atastypixel.com/blog/wp-content/uploads/2010/06/media_images_products_loopy_screen-iphone.jpg" width="190" height="397" alt="_media_images_products_loopy_screen-iphone.jpg" class="alignright" />Loopy, my loop-based musical instrument and musical notepad app, is going on sale in anticipation of Loopy 2, which is on its way, with a release expected a little later this year.</p>

<p>Here&#8217;s some recent feedback on Loopy (about which I&#8217;m thrilled!):</p>

<ul>
<li><em>Loopy does more of what I wanted than my Boss looper pedal that I paid £180 for!</em> <strong>CUJ1mmy</strong></li>
<li><em>This app lets me get creative. The timing and sync is perfect and has a very polished interface.</em> <strong>Joza coza</strong></li>
<li><em>This is an example of someone going the extra mile to take advantage of what the iPhone can do &#8211; a refreshing change from the 1000&#8242;s of apps that all look, sound, and probably taste, the same. Apple &#8211; give this guy a job!</em> <strong>Gerry</strong></li>
</ul>

<p>Grab Loopy for half price on the <a href="http://itunes.apple.com/app/loopy/id300257824?mt=8">iPhone App Store</a>!</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1939" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/loopy-is-on-sale/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Making of Talkie: Multi-interface broadcasting and multicast</title>
		<link>http://atastypixel.com/blog/the-making-of-talkie-multi-interface-broadcasting-and-multicast/</link>
		<comments>http://atastypixel.com/blog/the-making-of-talkie-multi-interface-broadcasting-and-multicast/#comments</comments>
		<pubDate>Sun, 02 May 2010 12:52:38 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Geekspeak]]></category>
		<category><![CDATA[Broadcast]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Multicast]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Talkie]]></category>
		<category><![CDATA[Talkie-for-Mac]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/?p=1901</guid>
		<description><![CDATA[Part 2 Talkie is my newest product, a Walkie Talkie for iPhone and Mac. In Part 1 of this series, I wrote about basic broadcasting. This works fine with one network device, but it&#8217;s worth discussing how to send through all devices, so you can communicate with others connected via, say, Ethernet and WiFi simultaneously. [...]]]></description>
			<content:encoded><![CDATA[<h2>Part 2</h2>

<p><img src="http://atastypixel.com/media/images/products/talkie/icon-medium.jpg" width="183" height="148" alt="Talkie" style="float:right;" /><a href="http://atastypixel.com/products/talkie">Talkie</a> is my newest product, a Walkie Talkie for iPhone and Mac.</p>

<p>In <a href="http://atastypixel.com/blog/2010/03/11/the-making-of-talkie-broadcasting/">Part 1</a> of this series, I wrote about basic broadcasting.  This works fine with one network device, but it&#8217;s worth discussing how to send through all devices, so you can communicate with others connected via, say, Ethernet and WiFi simultaneously.</p>

<p>So, in Part 2 I&#8217;ll write about the approach I took in Talkie for broadcasting from all network devices (a.k.a. network interfaces), so that one can communicate with others connected via WiFi, Ethernet (on a Mac), and any other network devices simultaneously.</p>

<p><span id="more-1901"></span></p>

<h2>Bind them</h2>

<p>From Part 1, we have a <a href="http://atastypixel.com/blog/2010/03/11/the-making-of-talkie-broadcasting/">working broadcast mechanism</a>, but it will only send through the default interface &#8212; whatever you&#8217;re connected to the network via.  This is often sufficient, but if you have more than one device that you communicate through, like Ethernet and WiFi, then you will find that it only works with one.</p>

<p>In order to send through <em>all</em> your connected network interfaces, we need to create one socket for each interface, and <em>bind</em> the socket to its corresponding interface.</p>

<p>Here&#8217;s how:</p>

<p>First, we need to obtain a list of all network interfaces with <code>getifaddrs</code>.</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#include &lt;ifaddrs.h&gt;</span>
...
<span style="color: #a61390;">struct</span> ifaddrs <span style="color: #002200;">*</span>addrs;
<span style="color: #a61390;">int</span> result <span style="color: #002200;">=</span> getifaddrs<span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>addrs<span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> result &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Error occurred</span>
  <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Now, <code>addrs</code> is a list of interfaces that we can iterate over.  We now do so, picking out those devices that support broadcasting, and that aren&#8217;t loopback or point-to-point devices &#8212; loopback is an internal interface that is provided for your computer&#8217;s inner dialogue, and point-to-point (ppp) devices include dialup interfaces, 3G modems and the like.  We can exclude those guys.</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">const</span> <span style="color: #a61390;">struct</span> ifaddrs <span style="color: #002200;">*</span>cursor <span style="color: #002200;">=</span> addrs;
<span style="color: #a61390;">while</span> <span style="color: #002200;">&#40;</span> cursor <span style="color: #002200;">!=</span> <span style="color: #a61390;">NULL</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> cursor<span style="color: #002200;">-</span>&gt;ifa_addr<span style="color: #002200;">-</span>&gt;sa_family <span style="color: #002200;">==</span> AF_INET 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_LOOPBACK<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_POINTOPOINT<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span>  <span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_BROADCAST<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// We will do some stuff in here</span>
&nbsp;
  <span style="color: #002200;">&#125;</span>
  cursor <span style="color: #002200;">=</span> cursor<span style="color: #002200;">-</span>&gt;ifa_next;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Now, for each interface that meets our criteria, we create a socket (which we covered in <a href="http://atastypixel.com/blog/2010/03/11/the-making-of-talkie-broadcasting/">Part 1</a>), then <code>bind</code> the socket to the network interface, to force transmission from that particular device.  Finally, as we did in Part 1, we enable broadcasting using <code>setsockopt</code> with <code>SO_BROADCAST</code>.</p>

<p>We want to store the sockets we create in an array, so we can access them later.  If we assume a maximum number of interfaces we will support (lets call it <code>kMaxSockets</code>), we can just use an array of that length.  So, putting it together:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define kMaxSockets 16</span>
...
<span style="color: #a61390;">int</span> sock_fds<span style="color: #002200;">&#91;</span>kMaxSockets<span style="color: #002200;">&#93;</span>;
<span style="color: #a61390;">int</span> number_sockets <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
&nbsp;
<span style="color: #a61390;">while</span> <span style="color: #002200;">&#40;</span> cursor <span style="color: #002200;">!=</span> <span style="color: #a61390;">NULL</span> <span style="color: #002200;">&amp;&amp;</span> number_sockets &lt; kMaxSockets <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> cursor<span style="color: #002200;">-</span>&gt;ifa_addr<span style="color: #002200;">-</span>&gt;sa_family <span style="color: #002200;">==</span> AF_INET 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_LOOPBACK<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_POINTOPOINT<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span>  <span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_BROADCAST<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Create socket</span>
    sock_fds<span style="color: #002200;">&#91;</span>number_sockets<span style="color: #002200;">&#93;</span> <span style="color: #002200;">=</span> socket<span style="color: #002200;">&#40;</span>AF_INET, SOCK_DGRAM, <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> sock_fds<span style="color: #002200;">&#91;</span>number_sockets<span style="color: #002200;">&#93;</span> <span style="color: #002200;">==</span> <span style="color: #002200;">-</span><span style="color: #2400d9;">1</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      <span style="color: #11740a; font-style: italic;">// Error occurred</span>
      <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Create address from which we want to send, and bind it</span>
    <span style="color: #a61390;">struct</span> sockaddr_in addr;
    <span style="color: #a61390;">memset</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #2400d9;">0</span>, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
    addr.sin_family <span style="color: #002200;">=</span> AF_INET;
    addr.sin_addr <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr_in <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">-</span>&gt;sin_addr;
    addr.sin_port <span style="color: #002200;">=</span> htons<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;
&nbsp;
    <span style="color: #a61390;">int</span> result <span style="color: #002200;">=</span> bind<span style="color: #002200;">&#40;</span>sock_fds<span style="color: #002200;">&#91;</span>number_sockets<span style="color: #002200;">&#93;</span>, <span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> result &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      <span style="color: #11740a; font-style: italic;">// Error occurred</span>
      <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Enable broadcast</span>
    <span style="color: #a61390;">int</span> flag <span style="color: #002200;">=</span> <span style="color: #2400d9;">1</span>;
    result <span style="color: #002200;">=</span> setsockopt<span style="color: #002200;">&#40;</span>sock_fds<span style="color: #002200;">&#91;</span>number_sockets<span style="color: #002200;">&#93;</span>, SOL_SOCKET, SO_BROADCAST, <span style="color: #002200;">&amp;</span>flag, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>flag<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> result <span style="color: #002200;">!=</span> <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      <span style="color: #11740a; font-style: italic;">// Error occurred</span>
      <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    number_sockets<span style="color: #002200;">++</span>;
  <span style="color: #002200;">&#125;</span>
  cursor <span style="color: #002200;">=</span> cursor<span style="color: #002200;">-</span>&gt;ifa_next;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Finally, as before, we can setup a broadcast address to send to, and use <code>sendto</code> to broadcast, this time for each socket we created:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Initialise broadcast address</span>
<span style="color: #a61390;">struct</span> sockaddr_in addr;
<span style="color: #a61390;">memset</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #2400d9;">0</span>, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
addr.sin_family <span style="color: #002200;">=</span> AF_INET;
addr.sin_addr.s_addr <span style="color: #002200;">=</span> INADDR_BROADCAST;
addr.sin_port <span style="color: #002200;">=</span> htons<span style="color: #002200;">&#40;</span>kPortNumber<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Send through each interface</span>
<span style="color: #a61390;">int</span> i;
<span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span> i<span style="color: #002200;">=</span><span style="color: #2400d9;">0</span>; i&lt;number_sockets; i<span style="color: #002200;">++</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">int</span> result <span style="color: #002200;">=</span> sendto<span style="color: #002200;">&#40;</span>sock_fds<span style="color: #002200;">&#91;</span>i<span style="color: #002200;">&#93;</span>, data, length, <span style="color: #2400d9;">0</span>, <span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> result &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// Error occurred</span>
    <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Note that the receive routine only needs a single socket, as we can receive on any interface when we use <code>INADDR_ANY</code>.  So, the receive routine needs no changes from the single-interface version we saw in Part 1.</p>

<p>Here&#8217;s the test app with the above modification: <a href="http://atastypixel.com/blog/wp-content/uploads/2010/05/broadcast_sample_all_interfaces.c" title="broadcast_sample_all_interfaces.c">broadcast_sample_all_interfaces.c</a></p>

<p>Again, compile by opening Terminal, and typing <code>make broadcast_sample_all_interfaces</code> or <code>cc -o broadcast_sample_all_interfaces broadcast_sample_all_interfaces.c</code>, then run it with <code>./broadcast_sample_all_interfaces "Message to send"</code> to send, or just <code>./broadcast_sample_all_interfaces</code> with no arguments to listen.</p>

<p>You may notice that multiple messages may be received: These have probably arrived via multiple network interfaces, virtual or otherwise.  It&#8217;s usually a good idea to check for duplicate messages, if this is an issue for program operation, by including a sequence number into the message &#8212; this will be discussed in Part 3.</p>

<p>It also may be a good idea to ignore your own messages, which may find their way back to you.  One way to accomplish this is to examine the source address (<code>addr</code> in the example above) and compare it with your local interface addresses (stored in <code>addrs</code>, above).  If you get a match, the message came from you, and you can drop it.</p>

<h2>Multicast</h2>

<p>Broadcast is fine when everyone on the local network is interested in what you have to say.  If this isn&#8217;t the case, though (lets face it, those Chuck Norris jokes aren&#8217;t for everyone), effort is wasted delivering to those who aren&#8217;t particularly interested.</p>

<p>Multicast works by using a specific address that one &#8216;subscribes&#8217; to in order to receive messages sent to that address.  So, it&#8217;s opt-in, allowing for better efficiency and one day, Internet-wide support for &#8216;to-many&#8217; communications.</p>

<p>Well, in theory.  Actually, multicast is still quite new, and for the most part &#8212; from what I understand &#8212; it behaves pretty much like broadcast on a local area network.  However, support can only increase, and given that many services already use it &#8212; Multicast DNS (mDNS), also known as Bonjour, being one of the most well-known examples &#8212; it seems a good idea to follow their lead.  Note also that IPv6, the successor to IP as we know it, and our saviour-to-be from our little Internet overpopulation problem (among other things), doesn&#8217;t even have broadcast provisions &#8212; the future is all multicast.</p>

<p>So, for these reasons, Talkie speaks multicast, instead of plain ol&#8217; broadcast.</p>

<p>Making use of multicast is relatively straightforward: To receive, you join a multicast group using <code>setsockopt</code> with <code>IP_ADD_MEMBERSHIP</code>, and the address of the multicast group, which is in the range 224.0.0.0-239.255.255.255 (for IPv4, of course).  To send, you just use <code>sendto</code> to transmit data to a multicast group address.</p>

<p>Using multicast on all network interfaces is just a little more complicated.  Here&#8217;s how it&#8217;s done with Talkie:</p>

<h3>Sending</h3>

<p>The send routine is very similar to the one above, using broadcast.  However, instead of using <code>bind</code> to specify the outgoing network interface and enabling broadcast, we assign a multicast interface using <code>setsockopt</code> with <code>IP_MULTICAST_IF</code>.  And, instead of transmitting to the broadcast address, we transmit to the multicast group address.</p>

<p>Again, we loop through all network interfaces.  This time, we pick out those that support multicast (<code>ifa_flags &amp; IFF_MULTICAST</code>):</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">const</span> <span style="color: #a61390;">struct</span> ifaddrs <span style="color: #002200;">*</span>cursor <span style="color: #002200;">=</span> addrs;
<span style="color: #a61390;">while</span> <span style="color: #002200;">&#40;</span> cursor <span style="color: #002200;">!=</span> <span style="color: #a61390;">NULL</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> cursor<span style="color: #002200;">-</span>&gt;ifa_addr<span style="color: #002200;">-</span>&gt;sa_family <span style="color: #002200;">==</span> AF_INET 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_LOOPBACK<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_POINTOPOINT<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span>  <span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_MULTICAST<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// We will do some stuff in here</span>
&nbsp;
  <span style="color: #002200;">&#125;</span>
  cursor <span style="color: #002200;">=</span> cursor<span style="color: #002200;">-</span>&gt;ifa_next;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>And, after creating the socket, we assign the interface:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> setsockopt<span style="color: #002200;">&#40;</span>sock_fds<span style="color: #002200;">&#91;</span>number_sockets<span style="color: #002200;">&#93;</span>, IPPROTO_IP, IP_MULTICAST_IF, <span style="color: #002200;">&amp;</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr_in <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">-</span>&gt;sin_addr, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> in_addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">!=</span> <span style="color: #2400d9;">0</span>  <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Error occurred</span>
  <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Finally, as a nicety, we can disable loopback so that we don&#8217;t receive our own messages.  This isn&#8217;t 100% reliable, as certain network conditions can result in the local machine still receiving its outgoing messages, but it can improve efficiency:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">u_char loop <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> setsockopt<span style="color: #002200;">&#40;</span>sock_fds<span style="color: #002200;">&#91;</span>number_sockets<span style="color: #002200;">&#93;</span>, IPPROTO_IP, IP_MULTICAST_LOOP, <span style="color: #002200;">&amp;</span>loop, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>loop<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">!=</span> <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Error occurred</span>
  <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Now that our sockets are set up, we can prepare to send to the multicast address:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define kMulticastAddress &quot;224.0.0.123&quot;</span>
...
<span style="color: #a61390;">memset</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #2400d9;">0</span>, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
addr.sin_family <span style="color: #002200;">=</span> AF_INET;
addr.sin_addr.s_addr <span style="color: #002200;">=</span> inet_addr<span style="color: #002200;">&#40;</span>kMulticastAddress<span style="color: #002200;">&#41;</span>;
addr.sin_port <span style="color: #002200;">=</span> htons<span style="color: #002200;">&#40;</span>kPortNumber<span style="color: #002200;">&#41;</span>;</pre></div></div>


<p>And, as before, we send through each of the sockets we created:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">int</span> i;
<span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span> i<span style="color: #002200;">=</span><span style="color: #2400d9;">0</span>; i&lt;number_sockets; i<span style="color: #002200;">++</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> sendto<span style="color: #002200;">&#40;</span>sock_fds<span style="color: #002200;">&#91;</span>i<span style="color: #002200;">&#93;</span>, data, length, <span style="color: #2400d9;">0</span>, <span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// Error occurred</span>
    <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<h3>Receiving</h3>

<p>Receiving messages from a multicast group on several network interfaces is a little more involved than doing so with broadcast: We need to subscribe to the multicast group from each network interface, explicitly.  If we were to just specify no device in particular, the system would choose a single interface for us, neglecting the others.</p>

<p>Joining the multicast group for each interface takes place in a now-familiar loop:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">const</span> <span style="color: #a61390;">struct</span> ifaddrs <span style="color: #002200;">*</span>cursor <span style="color: #002200;">=</span> addrs;
<span style="color: #a61390;">while</span> <span style="color: #002200;">&#40;</span> cursor <span style="color: #002200;">!=</span> <span style="color: #a61390;">NULL</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> cursor<span style="color: #002200;">-</span>&gt;ifa_addr<span style="color: #002200;">-</span>&gt;sa_family <span style="color: #002200;">==</span> AF_INET 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_LOOPBACK<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_POINTOPOINT<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span>  <span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_MULTICAST<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// We will do some stuff in here</span>
&nbsp;
  <span style="color: #002200;">&#125;</span>
  cursor <span style="color: #002200;">=</span> cursor<span style="color: #002200;">-</span>&gt;ifa_next;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>For each network device, we use the <code>IP_ADD_MEMBERSHIP</code> property with <code>setsockopt</code> to join &#8212; thereby subscribing to any messages sent to the multicast group address that reach that network interface.</p>

<p>First, we prepare the join request structure.  This provides the multicast group address, and the network interface:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">struct</span> ip_mreq multicast_req;
<span style="color: #a61390;">memset</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>multicast_req, <span style="color: #2400d9;">0</span>, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>multicast_req<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
multicast_req.imr_multiaddr.s_addr <span style="color: #002200;">=</span> inet_addr<span style="color: #002200;">&#40;</span>kMulticastAddress<span style="color: #002200;">&#41;</span>;
multicast_req.imr_interface <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr_in <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">-</span>&gt;sin_addr;</pre></div></div>


<p>Now we use this structure to join the group:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> setsockopt<span style="color: #002200;">&#40;</span>sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, <span style="color: #002200;">&amp;</span>multicast_req, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>multicast_req<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Error occurred</span>
  <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Now, a caveat: While it&#8217;s perfectly legal to join the same multicast group on more than one network interface, and up to 20 memberships may be added to the same socket (see <a href="http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man4/ip.4.html">ip(4)</a>), for some reason, OS X spews &#8216;Address already in use&#8217; errors when we actually attempt it.</p>

<p>As a workaround, we can &#8216;drop&#8217; the membership first, which would normally have no effect, as we have not yet joined on this interface.  However, it enables us to perform the subsequent join, without dropping prior memberships.</p>

<p>So, before we perform the above <code>IP_ADD_MEMBERSHIP</code>, we do a <code>IP_DROP_MEMBERSHIP</code> first:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">setsockopt<span style="color: #002200;">&#40;</span>sock_fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, <span style="color: #002200;">&amp;</span>multicast_req, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>multicast_req<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;</pre></div></div>


<p>This sets up our socket to receive messages sent to the multicast group that are received via any interface.</p>

<p>Here it is all put together: <a href="http://atastypixel.com/blog/wp-content/uploads/2010/05/multicast_sample.c" title="multicast_sample.c">multicast_sample.c</a></p>

<p>Compile by opening Terminal, and typing <code>make multicast_sample</code> or <code>cc -o multicast_sample multicast_sample .c</code>, then run it with <code>./multicast_sample "Message to send"</code> to send, or just <code>./multicast_sample</code> with no arguments to listen.</p>

<h2>Still to come</h2>

<p>So, now we mostly have networking covered.  There&#8217;s one obvious omission, though, for an iPhone app: Bluetooth.  In Part 3, I&#8217;ll discuss how to perform communications over Bluetooth on the iPhone, in a way that&#8217;s compatible with the above generic network communications.  I&#8217;ll also talk about how to connect to other devices automatically, without user intervention &#8212; This is one particularly popular feature of Talkie that allows it to behave more like a real walkie-talkie.</p>

<p>I promised in Part 1 that I&#8217;d talk about packet formats.   We&#8217;ve covered a lot of ground in Part 2, however, so it shall be postponed to Part 3 &#8212; I&#8217;ll discuss how to ensure you get messages in the correct order by using sequence numbers, as well as providing for versioning and a few other bits and pieces.</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1901" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/the-making-of-talkie-multi-interface-broadcasting-and-multicast/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Making of Talkie: Broadcasting</title>
		<link>http://atastypixel.com/blog/the-making-of-talkie-broadcasting/</link>
		<comments>http://atastypixel.com/blog/the-making-of-talkie-broadcasting/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 00:31:59 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Geekspeak]]></category>
		<category><![CDATA[Broadcast]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Talkie]]></category>
		<category><![CDATA[Talkie-for-Mac]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/?p=1854</guid>
		<description><![CDATA[Part 1 Talkie is my newest product, the result of a collaboration with a good designer friend, Tim Churchward, who did the user interface. Talkie is a little different from many of the other walkie talkie applications on the App Store (aside from the fact that much of it was written by me from our [...]]]></description>
			<content:encoded><![CDATA[<h2>Part 1</h2>

<p><img src="http://atastypixel.com/media/images/products/talkie/icon-medium.jpg" width="183" height="148" alt="Talkie" style="float:right;" /><a href="http://atastypixel.com/products/talkie">Talkie</a> is my newest product, the result of a collaboration with a good designer friend, Tim Churchward, who did the user interface.</p>

<p>Talkie is a little different from many of the other walkie talkie applications on the App Store (aside from the fact that much of it was written by me from our motorhome in <a href="http://michael.tyson.id.au/2010/01/26/down-time-in-hammamet/">Tunisia</a>!), and I thought I&#8217;d write a little about some of the tech underpinning the app, and some of the choices we made.   Along the way it may get a little tutorial-esque.</p>

<ul>
<li>This first part will introduce our initial motivations, and will talk about basic broadcast communications &#8212; the broadcast communications part may be very familiar to some, in which case it may be worth skipping to the next instalment.</li>
<li>In the <a href="http://atastypixel.com/blog/the-making-of-talkie-broadcasting/">second part</a>, I&#8217;ll continue the theme of networking, and will talk about what I ended up with for Talkie&#8217;s network code after addressing a couple of things, including switching to multicast.  </li>
<li>Finally, I&#8217;ll talk audio, dual platform development, and anything else I think of along the way (Actually, I&#8217;m aching to talk about one particular upcoming feature that had me jumping up and down when I first thought of it, but for now, mum&#8217;s the word on that one.)<span id="more-1854"></span>## Inspiration</li>
</ul>

<p><img src="http://atastypixel.com/media/images/products/talkie/screen-iphone.jpg" width="187" height="400" alt="Talkie screenshot" style="float:right;" />Right from the start, we wanted a product that brought back the fun walkie talkie experience we remember from our childhoods.  I&#8217;m talking colourful plastic, whip antennas and hiding in tree-houses.   This was mostly Tim&#8217;s domain, so I shall leave it to him to discuss how he found that in the user interface.</p>

<p>It also meant stepping back from traditional voice chat, with manual call initialisation and termination and simple one-to-one calls.  We wanted to mimic a radio, so that meant broadcasting as soon as you hit &#8220;Talk&#8221; &#8212; whereupon anyone in the neighbourhood would hear you.</p>

<p>Basically, we wanted to get as close to the real thing as was practical.  This included the addition of a prominent &#8216;morse code&#8217; button, of course, as well as a &#8216;squelch&#8217; control for &#8216;fine tuning&#8217;, which simulated the static of bad reception.</p>

<h2>Going dual-platform</h2>

<p><img src="http://atastypixel.com/media/images/products/talkie-for-mac/screenshot.jpg" width="232" height="190" alt="Talkie for Mac" style="float:left;" />Soon after I started developing Talkie, I realised I wanted a version for the Mac too.</p>

<p>Having Talkie both on the iPhone and on the Mac made sense, as we envisioned that a fairly common usage pattern would involve communication between a desktop and a handheld &#8212; say, someone wandering a campus with the iPhone in their pocket, staying in touch with friends at their desks.</p>

<p>We wanted to offer good value with Talkie, which is why we made Talkie for Mac available for free, when it&#8217;s used with Talkie for iPhone.</p>

<p>One of the very convenient things about developing for both iPhone and Mac is that the platforms are so similar, porting code is usually effortless.  So, going dual-platform was an easy decision.</p>

<h2>Finding common ground</h2>

<p>The result of all of this was the need to develop or find a communication protocol and codec that would work across the iPhone and the Mac, over both Bluetooth for iPhone-iPhone communication, and Wifi, for communication between iPhones and iPhones, and iPhones and Macs.</p>

<p>Version 3.0 of the iPhone SDK introduced the GameKit framework and as part of it, <code>GKVoiceChatService</code>, which provides two person voice chat straight out of the box.  Immediately it was clear that it wouldn&#8217;t serve our purposes &#8212; two person is not broadcast.  I was also keen to provide a Mac version of Talkie, and given that GameKit is iPhone-only, it was time to go off the beaten track.</p>

<p>There are a variety of voice communication protocols out there, with varying licences and varying complexity and feature sets.  I could&#8217;ve spent a week or two researching the options and evaluating them against our need for broadcast functionality, figuring out compilation and linking on the iPhone, resolving any compatibility or performance issues that arose, etc.</p>

<p>Or, I could spend a day putting together a few big building blocks provided by Apple (and the underlying Unix system) and have an easily tweakable working solution that precisely meets our needs and provides for future features.</p>

<p>It may not have been the most scientific approach, but the core of Talkie&#8217;s functionality was up and running on our home wi-fi network within about four hours, and it was working well.</p>

<h2>Getting from a to b (and c, d, e, and f)</h2>

<p>For those unfamiliar with the ins and outs of TCP/IP (the most common communication protocol &#8212; or rather, set of protocols &#8212; between computers, and the fundamental building block of the Internet), communication between computers can be connection-oriented, or connectionless.</p>

<p>Connection-oriented (a.k.a. &#8216;reliable&#8217;) communications are most common: They&#8217;re used when you open up a website, connect to iChat, or check your email.  This is the TCP part of TCP/IP, and includes niceties like built-in guaranteed delivery via retransmission (providing your cat hasn&#8217;t eaten your network cable, of course) and packet ordering so you receive the messages in the right order.  This only works between two computers, though &#8211; you and the server.</p>

<p>Connectionless (or &#8216;unreliable&#8217;) communications are much more open &#8212; it&#8217;s basically just a spray of messages: The data isn&#8217;t carefully ushered along, it&#8217;s just spat out and left to fend for itself.  This is UDP, and is commonly used for time-sensitive applications like audio communication, network gaming, etc., where once a packet arrives late, it&#8217;s useless: No point mucking about re-sending lost data that&#8217;s going to be past its use-by date by the time it arrives.  The other thing about UDP is that, because there&#8217;s no co-operation required from the destination (to acknowledge receipt, etc.), it lends itself to one-to-many communications &#8212; broadcast.</p>

<p>Just what we&#8217;re after.</p>

<p>So, we use connectionless communications (UDP) to send messages containing the audio, and anyone who receives them unpackages and plays the audio within.</p>

<p>The basic mechanics of this are fairly simple, once you get past the arguably cryptic C syntax.</p>

<p>Here&#8217;s how it works.</p>

<h3>Sending</h3>

<p>On the transmission end, on startup, you create a socket using the <code>socket</code> call:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#include &lt;sys/socket.h&gt;</span>
<span style="color: #6e371a;">#include &lt;netinet/in.h&gt;</span>
<span style="color: #6e371a;">#include &lt;arpa/inet.h&gt;</span>
...
<span style="color: #a61390;">int</span> sock_fd <span style="color: #002200;">=</span> socket<span style="color: #002200;">&#40;</span>AF_INET, SOCK_DGRAM, <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> sock_fd &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
   <span style="color: #11740a; font-style: italic;">// Error occurred</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>The socket, identified by <code>sock_fd</code>, will be created using the IPv4 domain (<code>AF_INET</code>), a &#8216;datagram&#8217; type (<code>SOCK_DFRAM</code>: that&#8217;s connectionless communication &#8212; if we wanted connection-oriented, we could put in <code>SOCK_STREAM</code> here instead), using protocol 0, which is IP.</p>

<p>Then, we enable broadcasting:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">int</span> flag <span style="color: #002200;">=</span> <span style="color: #2400d9;">1</span>;
<span style="color: #a61390;">int</span> result <span style="color: #002200;">=</span> setsockopt<span style="color: #002200;">&#40;</span>sock_fd, SOL_SOCKET, SO_BROADCAST, <span style="color: #002200;">&amp;</span>flag, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>flag<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> result &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
   <span style="color: #11740a; font-style: italic;">// Error occurred</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>That is, we set the <code>SO_BROADCAST</code> option at the <code>SOL_SOCKET</code> level to 1 (via the <code>flag</code> variable, which we pass in as a pointer), thereby requesting permission from the operating system kernel to broadcast.</p>

<p>Now we have the carrier pigeon coop at our disposal, we can start dispatching pigeons.  First, we fill out the address:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define kPortNumber 1234</span>
...
<span style="color: #a61390;">struct</span> sockaddr_in addr;
<span style="color: #a61390;">memset</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #2400d9;">0</span>, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
addr.sin_family <span style="color: #002200;">=</span> AF_INET;
addr.sin_addr.s_addr <span style="color: #002200;">=</span> INADDR_BROADCAST;
addr.sin_port <span style="color: #002200;">=</span> htons<span style="color: #002200;">&#40;</span>kPortNumber<span style="color: #002200;">&#41;</span>;</pre></div></div>


<p>(Note, <code>htons</code> converts <code>kPortNumber</code> into a format that can be understood by any computer, regardless of the way it represents numbers internally.)</p>

<p>Now, send:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>dataToSend;
result <span style="color: #002200;">=</span> sendto<span style="color: #002200;">&#40;</span>sock_fd, <span style="color: #002200;">&#91;</span>data bytes<span style="color: #002200;">&#93;</span>, <span style="color: #002200;">&#91;</span>data length<span style="color: #002200;">&#93;</span>, <span style="color: #2400d9;">0</span>, <span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> result &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
   <span style="color: #11740a; font-style: italic;">// Error occurred</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<h3>Receiving</h3>

<p>That takes care of outgoing messages.  To receive them, we want another socket:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">int</span> sock_fd <span style="color: #002200;">=</span> socket<span style="color: #002200;">&#40;</span>AF_INET, SOCK_DGRAM, <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> sock_fd &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
   <span style="color: #11740a; font-style: italic;">// Error occurred</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Now we specify where we want to receive messages from, by &#8216;binding&#8217; the socket:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">struct</span> sockaddr_in addr;
<span style="color: #a61390;">memset</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #2400d9;">0</span>, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
addr.sin_family <span style="color: #002200;">=</span> AF_INET;
addr.sin_addr.s_addr <span style="color: #002200;">=</span> INADDR_ANY;
addr.sin_port <span style="color: #002200;">=</span> htons<span style="color: #002200;">&#40;</span>kPortNumber<span style="color: #002200;">&#41;</span>;
result <span style="color: #002200;">=</span> bind<span style="color: #002200;">&#40;</span>sock_fd, <span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> result &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Error occurred</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>And we pass a buffer to <code>recvfrom</code> to fill up with tasty morsels of data:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define kBufferSize 1024</span>
...
<span style="color: #a61390;">char</span> buffer<span style="color: #002200;">&#91;</span>kBufferSize<span style="color: #002200;">&#93;</span>;
<span style="color: #a61390;">int</span> addr_len <span style="color: #002200;">=</span> <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">int</span> bytes_received <span style="color: #002200;">=</span> recvfrom<span style="color: #002200;">&#40;</span>sock_fd, buffer, kBufferSize, <span style="color: #2400d9;">0</span>, <span style="color: #002200;">&#40;</span>struck sockaddr<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #002200;">&amp;</span>addr_len<span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> bytes_received &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
   <span style="color: #11740a; font-style: italic;">// Error occurred</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Voila, we have <code>bytes_received</code> bytes sitting in <code>buffer</code> for us to do something with.  Note also that <code>addr</code> now also contains the address of the sender.  Now we can loop and continue to receive data as it comes in, passing the data off to some other part of the application to deal with.</p>

<p>We can put it all together into a simple test app: <a href="http://atastypixel.com/blog/wp-content/uploads/2010/03/broadcast_sample.c" title="broadcast_sample.c">broadcast_sample.c</a></p>

<p>Compile it by opening up Terminal, and typing <code>make broadcast_sample</code> (or <code>cc -o broadcast_sample broadcast_sample.c</code>, if you like), then run it with <code>./broadcast_sample "Message to send"</code>, or just <code>./broadcast_sample</code> to listen.</p>

<p><pre>
$ ./broadcast_sample 
Listening...
Hello world!
</pre></p>

<p><pre>
$ ./broadcast_sample 'Hello world!'
"Hello world!" transmitted.
</pre></p>

<h2>Coming next</h2>

<p>This will work happily between computers with just one network interface. But, if you have more than one (say, wireless, and an Ethernet connection too), you&#8217;ll notice that it will only communicate through one of the interfaces.  That&#8217;s because just the default interface is used.  You have to explicitly attend to each interface, to broadcast out of each one, and listen on each one.</p>

<p>In the <a href="http://atastypixel.com/blog/the-making-of-talkie-broadcasting/">next part of this series</a>, I&#8217;ll write about how I addressed that, and about multicast, which is used in things like Bonjour (MDNS).  I&#8217;ll also write about designing packet formats.</p>

<p>Thanks for reading!</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1854" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/the-making-of-talkie-broadcasting/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Talkie 1.1 for iPhone</title>
		<link>http://atastypixel.com/blog/talkie-1-1-for-iphone/</link>
		<comments>http://atastypixel.com/blog/talkie-1-1-for-iphone/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 14:06:27 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Products]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Talkie]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/2010/01/22/talkie-1-1-for-iphone/</guid>
		<description><![CDATA[Talkie 1.1 is now available on the iPhone App Store, and it&#8217;s better than ever. The new version connects to other Talkies via Bluetooth completely automatically &#8212; start Talkie on your iPhone and within seconds you&#8217;ll be connected to anyone nearby using Talkie on the same channel. Also new are WiFi and Bluetooth connection indicators, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://atastypixel.com/blog/wp-content/uploads/2010/01/media_images_products_talkie_screen-iphone.jpg" width="187" height="400" alt="Talkie 1.1" class="alignright" />Talkie 1.1 is now <a href="http://itunes.apple.com/app/talkie/id346221772?mt=8">available on the iPhone App Store</a>, and it&#8217;s better than ever.</p>

<p>The new version connects to other Talkies via Bluetooth completely automatically &#8212; start Talkie on your iPhone and within seconds you&#8217;ll be connected to anyone nearby using Talkie on the same channel.</p>

<p>Also new are WiFi and Bluetooth connection indicators, and an audio meter for when you&#8217;re transmitting or receiving.</p>

<p>For a limited time only, Talkie is available for $1.99.  Grab it on the <a href="http://itunes.apple.com/app/talkie/id346221772?mt=8">app store</a>.</p>

<p>&#8211; And don&#8217;t forget, <a href="http://atastypixel.com/products/talkie-for-mac">Talkie for Mac</a> is absolutely, 100% free for use with Talkie for iPhone.</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1829" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/talkie-1-1-for-iphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Tasty Pixel’s store and Talkie for Mac Premium</title>
		<link>http://atastypixel.com/blog/a-tasty-pixels-store-and-talkie-for-mac-premium/</link>
		<comments>http://atastypixel.com/blog/a-tasty-pixels-store-and-talkie-for-mac-premium/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 14:51:25 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Products]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Talkie-for-Mac]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/2010/01/04/a-tasty-pixels-store-and-talkie-for-mac-premium/</guid>
		<description><![CDATA[I&#8217;m happy to announce that the store is now open for business! We accept PayPal and all major credit cards, in four currencies. Talkie for Mac 1.0 is now available, and can be registered to access the features of Talkie for Mac Premium: Talk to others using the free version of Talkie for Mac Push-to-talk [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://atastypixel.com/media/images/products/talkie-for-mac/icon-small.png" class="alignright" />I&#8217;m happy to announce that the <a href="http://atastypixel.com/store">store</a> is now open for business!  We accept PayPal and all major credit cards, in four currencies.</p>

<p><a href="http://atastypixel.com/download/talkie-for-mac">Talkie for Mac 1.0</a> is now available, and can be <a href="http://atastypixel.com/store/talkie-for-mac">registered</a> to access the features of Talkie for Mac Premium:</p>

<ul>
<li>Talk to others using the free version of Talkie for Mac</li>
<li><em>Push-to-talk calls with anyone over the Internet, coming next in Talkie for Mac 2.0</em></li>
</ul>

<p>&#8230;On top of the features of the free version of Talkie for Mac, of course:</p>

<ul>
<li>Zero-configuration operation: Start Talkie, and start talking</li>
<li>12 distinct channels</li>
<li>Configurable global hotkey to transmit while performing other tasks</li>
<li>Unobtrusive interface</li>
<li>Incoming and outgoing audio indicators</li>
<li>Mute facility</li>
<li>Talk to others using <a href="http://atastypixel.com/products/talkie">Talkie for iPhone</a> or Talkie for Mac Premium.</li>
</ul>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1727" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/a-tasty-pixels-store-and-talkie-for-mac-premium/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Talkie for Mac is here</title>
		<link>http://atastypixel.com/blog/talkie-for-mac-is-here/</link>
		<comments>http://atastypixel.com/blog/talkie-for-mac-is-here/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 17:43:16 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Products]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Talkie-for-Mac]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/2009/12/22/talkie-for-mac-is-here/</guid>
		<description><![CDATA[Talkie for Mac is here! Note: Talkie has been retired since mid-2011. It may return at a later date. This post remains for historical purposes only. The current features of Talkie for Mac: Zero-configuration operation: Start Talkie, and start talking 12 distinct channels Configurable global hotkey to transmit while performing other tasks Unobtrusive interface Incoming [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://atastypixel.com/blog/wp-content/uploads/2009/12/talkie.png" width="128" height="128" alt="Talkie" class="alignright" /><a href="http://atastypixel.com/products/talkie-for-mac">Talkie for Mac</a> is here!</p>

<p><strong>Note: Talkie has been retired since mid-2011. It may return at a later date. This post remains for historical purposes only.</strong></p>

<p>The current features of Talkie for Mac:</p>

<ul>
<li>Zero-configuration operation: Start Talkie, and start talking</li>
<li>12 distinct channels</li>
<li>Configurable global hotkey to transmit while performing other tasks</li>
<li>Unobtrusive interface</li>
<li>Incoming and outgoing audio indicators</li>
<li>Mute facility</li>
</ul>

<p>The application can be used with <a href="http://atastypixel.com/products/talkie">Talkie for iPhone</a> for free, as well as with the registered version of Talkie for Mac, codenamed &#8216;Talkie for Mac Premium&#8217;.</p>

<p>To talk to others using the free version of Talkie for Mac, though, Talkie for Mac Premium is $4.99 &#8212; available as soon as the store is up and running.</p>

<p>So, go and <a href="http://atastypixel.com/products/talkie-for-mac">grab a copy of Talkie for Mac now!</a>  Then, leave a comment below and tell me what you think.</p>

<p><img src="http://atastypixel.com/blog/wp-content/uploads/2009/12/screenshot.jpg" width="232" height="190" alt="Talkie for Mac Screenshot" class="aligncenter" /></p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1723" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/talkie-for-mac-is-here/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Introducing Talkie</title>
		<link>http://atastypixel.com/blog/introducing-talkie/</link>
		<comments>http://atastypixel.com/blog/introducing-talkie/#comments</comments>
		<pubDate>Sat, 19 Dec 2009 19:52:28 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Products]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Talkie]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/2009/12/19/introducing-talkie/</guid>
		<description><![CDATA[A Tasty Pixel&#8217;s new application has hit the App Store: Talkie! This bad boy stands out from the crowd with an engine that works not only over Bluetooth, but also over WiFi networks. Talkie will broadcast over the network so that any other iPhones running the same app &#8212; or any Macs running Talkie for [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://atastypixel.com/blog/wp-content/uploads/2009/12/Talkie-Icon.png" width="128" height="128" alt="Talkie" class="alignright" />
A Tasty Pixel&#8217;s new application has hit the App Store: <a href="http://atastypixel.com/products/talkie">Talkie</a>!</p>

<p>This bad boy stands out from the crowd with an engine that works not only over Bluetooth, but also over WiFi networks.  Talkie will broadcast over the network so that any other iPhones running the same app &#8212; or any Macs running Talkie for Mac &#8212; will pick up the signal.  No setup needed, it just works.</p>

<p>Should be great for uni students, or folks in large offices, and Talkie for Mac should fill the gaps for those without iPhones.</p>

<p>Talkie for Mac will come in a free edition, which offers two-way communication with the paid versions of Talkie, and the &#8216;pro&#8217; edition which works with everything.  That means you only need to buy one copy, then set your friends up with the free version to talk away.</p>

<p>Over the next few weeks I&#8217;ll be writing a little about Talkie&#8217;s guts and development, so stay tuned.</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1717" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/introducing-talkie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

