---
title: WWDC2001 Session 136
framework: wwdc
role: article
path: wwdc/wwdc2001-136
---

# WWDC2001 Session 136

## Transcript

Kind: captions Language: en welcome we're gonna have a session no 136 sound the networking for games I'd like to welcome you all I love David Hill and table Previn will be giving this presentation we're gonna do a tag-team event right here I think David's gonna lead it off talking about some sound and specific sounding games issues and talking about both the core graphics and sound manager and then Todd will follow up we're talking about networking talking about all the various networking services we have across the OS for games so without further ado David Hill for sound so as Jeff mentioned Todd and I will be splitting this session I'm gonna start out give you kind of a brief overview of the api's that we have available on Mac OS 10 and cover some of your options cover a little bit about how to set up and initialize each one then talk briefly about how to play back you know sound sample that's actually gonna be in core audience replay back and forth at all leverage quick time to do the one-page mp3 player then Todd is going to come up a little later and talk about a number of different networking issues bsd sockets addressing setup and initialization and some of the network technologies you might want to look into using for your games at Mac OS 10 and finally follow up and finish up with some tips and tricks so as far as the technologies were going to cover today as I said I'm gonna start out with the carbon sound manager tell you a little bit about what's changed and what hasn't I'm going to talk briefly about QuickTime in core audio and then Todd is going to be covering open transport Nets broken open play and some bsd sockets to the carbon soundmanager we brought the soundmanager across from Mac OS 8 & 9 to help make your jobs a lot easier it's callable both from CFM and ma co which makes it really nice since you can create a CFM app that uses the carbon sound manager that for the most part with no real changes at all will run on 8 & 9 and it will also run on Mac OS 10 it's also accessible from carbon and cocoa so cocoa has its own in a sound class but if for some reason you already have carbon sound manager code or you need a little bit more control than an S sound gives you what have you you can actually call it from cocoa that works just fine well one of the new things we've added as far as Mac OS 10 is though the carbon salmon directly now supports variable bitrate decoding that's a big issue for mp3s and things like that where they start to try to actually vary the bitrate to improve the compression that you get with your sounds however we have had to remove several api's for one reason or another probably the biggest one that we've heard people complain about are the sound play double buffer a number of people were using that one to do a real easy you know ping-pong back and forth between sent to sound buffers that one is no longer present in the carbon sound manager and in order to help you for those of you that we're using that API we've got a very good sample called the carbon sound play double buffer and encourage you to check that out it's on the sample code website that developer.apple.com slash sample code probably under the sound section there it's a pretty good sample it explains how to use the carbon sound manager and some other API to do pretty much the same thing that carbon or that the sound kway double buffer did before we've also removed some of the disk based api's the ones that played directly from a file and things like that and wavetable synthesis is no longer there for an example for the really curious among you there's some other changes under the hood between macros 89 and Mac OS 10 that your app probably shouldn't care about but I thought I'd mention them for those of you that are interested on Mac OS 8 and 9 the sound manager was this big global thing and it was actually only one on the whole system and the hardware model was provided by the sound manager itself it had to know about all the different sound hardware on every single machine and figure out what machine you were running on and do the right thing on Mac OS 10 however the sound managers process and in talking to the audio guys shouldn't make any difference to your app pretty much or either changing you know say the volume on a sound channel which is local to your app or you're changing the global volume which is still global so you shouldn't really care about that one either another interesting point is the hardware model on Mac OS 10 the carbon sound manager is actually a layer on top of core audio so that will introduce a slight performance hit perhaps but again your app shouldn't really make you know care one way or the other so I thought I'd step through just real briefly for those that haven't seen the carbon sound manager want to know what it looks like we can step through a little bit of code really just a few slides here so one important thing you need to have if you're using the buffer and callback scheme is you need a sound callback and prototype that up there at the top it takes the sound channel parameter and the sound command and then when you actually want to create a channel the channel is the thing that you actually send your sound commands to to play your buffers you pass it a pointer to a sound channel you pass it in this case we're telling it we want to send sampled sound we want a stereo Channel and then we pass in that callback when you get ready to play a sound you need to tell the sound manager what format that sound is them and so in this case we're filling out a header structure then these are just some of the interesting parameters you have a pointer to the sound data you're playing how many channels are in that sound the sample rate and we also tell if this is an extended sound header which lets you do some additional things you can set the base frequency I think number of frames isn't an extended sound manager thing samples per buffer and sample size so we're playing 16-bit stereo 44 kilohertz sound in this case so once you've got the channel set up and you've got the header set up you'd actually send those commands to the sound Channel and the first block of code there we set up what's called a buffer command so the buffer command simply tells the sound manager here's a block of sound data that I want you to play and we pass the header appointed to the header that we've just created that describes and detail the format of the sound and we pass that to the sound Channel with the sound Duke command the second block of code there let me just get through these in order to know when that buffer of sound is completed so that you can cue up the next buffer of sound you can pass in a callback command and I believe we have a bunch of sample to do this QuickTime does this kind of sound playing you pass in a callback command the parameters don't really matter and you pass that to the sound channel through much the same as you did before now one interesting thing to note and this confused me at first when I first started looking at this API you you're giving it a callback command but you're not telling it what to call back and if you remember we actually passed that in when we created the channel so that's one sound callback is set per channel it's not per callback command so you have to have all your callbacks on a particular channel go through one one actual callback function and then once you're done with the channel and after you send a number of buffers played whatever you want to don't forget to dispose it so moving on to quick time I'll put in a little plug for quick time here since this is a game session quick time is really good for complicated sound data like mp3s and midis they do all the heavy lifting for you but it's also really good for still image looking anybody that saw Jeff's 2d high performance to do OpenGL talk he uses QuickTime to do the image loading so he doesn't care what format it's in he just says QuickTime let me you know load in this image whatever format jpg BMP you know PNG whatever and QuickTime does all that work for and puts it into a buffer then he can hand that directly to OpenGL as a texture so it's really good for that it's especially good way to get some things prototyped and up and running if you want to do your own graphic format later you can but at least to get you started quick times a great way to get started and of course will be playing time is famous for that but I thought I'd throw it on there anyway so as promised here's a one page mp3 player to get QuickTime started enter movies and in this case we've passed it in a file spec of the file we want to play and in my demo code that I'll show you in a minute we actually just use nap services get us a file pass it in here we open the movie file say create a movie from the file and that will give us for that ref numb then we get out of open movie file it will give us a movie the structure fill out the movie structure that we can pass to the other api's and then to play it really simple we start the movie as long as movies not done we call movies tasks then when we're done we dispose the movie close the movie file and exit movies we're done so all it takes to play an mp3 really simple stuff I'll prove it so we go to the demo to machine this is a real simple app essentially the carbon basic carbon template from project builder through and pretty much that code you saw there [Music] easy stuff now there are some more in-depth samples on our website again for how to play mp3s if you want some more control over how its decoded and how it's played check out our sample code side I know there's some that more directly use the carbon sound manager and QuickTime together to play some more detailed things let's go back to the slides thank you let's talk about the new guy for audio so the number of core ideas sessions I think one has already occurred and two more coming up I'll tell you about them in a little bit but I wanted to go over kind of a high-level look at core audio so that you could get a feel for what it is and whether you should be looking at it for your game so choreo is a pretty low level interface provides a number of capabilities built into the architecture some of these are ready to go now some of them haven't been exposed yet but for one audio device sharing of course you want to make it easy for different devices to share different processes to share the same device if you have say an mp3 player playing and your game comes up and wants to be playing audio and then the system wants to beep to tell you something important happens everything has to be able to share it in the example code that I'll show you in a bit we just pretty much asked for audio for the default output device we say whatever you know sound goes to by default that's cool for us there are other calls that you can use to get more interesting info actually get a list of the different audio devices available things like that kirara also provides some facilities for real-time audio inter-process communication and that would essentially let multiple processes sort of pipe audio data between them so if you had one app that was generating some audio and another thing you wanted to send it to say an app that was recording that in some format or whatever you could actually chain them together and that's on a processed basis they also have a lower level what they call the audio unit and component model where you can actually have audio processing units and string them together within your app so you might in your app create the reverb unit and you know some other units together chain them together and then start sending audio through it one of the other interesting things about quality o is it's designed with low latency and it's supposed to be able to handle really well wait and see and also synchronize output between different sounds and a one interesting note there is you can actually control for the most part the latency in your app unlike the sound manager with core audio you can actually set for a given device what you want the buffer size to be and on nine there was always a big problem between VM on and VM off for games and the carbon sound manager are actually just the regular sound manager with VM on the system would make the buffer much bigger and so if you decided to change what you were playing you'd have to wait for that buffer to complete before the next buffer got going on core audio on Mac OS 10 that's not a problem you can set the buffer as big or small as you want now one got chip with core audio is the quality uses floating-point samples now that does greatly simplify your application code especially in the demo I'll show you we're denim generating tones and things like that it's really easy to generate but doesn't make the drivers work a little bit harder because the existing hardware we have right now sends integer data to the cards also if you're coming from say a conversion where you have wave sounds of some things like that coming from Windows or some other platform that are 8 or 16-bit integers you're probably going to have to convert your code convert your samples as on-the-fly or you can pre convert them and store them on disk in floating point samples one thing is that altivec will really help you there I understand there's a Veck CTF function that can do integer to float conversions very quickly you need to watch out for alignment issues there since altivec wants to deal in 16 byte chunks of data you don't want to make altivec do extra work too so in the carbon sale manager you got sound samples into the system using the buffer commands and the callback so that was your basic mechanism for getting sound into that system with core audio you deal with these things called i/o procs and so for a given device you can install one or more IO prongs and your i/o procs when they get called get a number of very interesting parameters they get a number of timestamps as I mentioned core audio was designed so that you could actually synchronize audio well if you're gonna synchronize audio you need to know a lot of stuff like what time is it now as far as the sound system is concerned and when are you gonna play this sound that I'm getting ready to hand you you know you've asked me to fill this buffer when's that buffer actually gonna get played so you get that information you'll get some info input buffers back as the name implies it's both input and output brock so you get some input buffers if the device is actually needing to send you data that's where that will come in and then there's a chunk of output buffers that you can use to put your samples in and send the data out to the card now last bullet there if you need to know what the stream is like you need to know how many channels or sample rate and those kinds of things you can actually make a call to get the que audio device property stream configuration you have another API with really long name names you can make this call and it'll fill out a structure for you that will give you very detailed information about what this i/o proc is going to get and what the stream is like now for the people that are really curious we can go into how the actual audio gets to the device for each device on the system there's one real-time mock thread that's pretty high priority and it goes it takes care of actually calling all the i/o procs when the i/o needs to when the system needs to move stuff back and forth and the sensor that device starts that thread up with the first i/o proc you install as soon as you activate the device with the first i/o proc the device is up and this threads running and calling your I Oprah and the threat stays running until you actually remove your last IO Croc and then it shuts back down again so let's look a little bit of what that thread looks like this is some real high-level pseudo code essentially loops until it's done it sleeps until it has something to do they can tell when the next input or output needs to happen sleeps until then then it looks to see if the device has input coming back into the end of the system if it does it'll calculate exactly when that input was sampled and then copy that data into the input buffers to get ready to handle the IO procs then it says ok does the device have output is it somebody installed on Io proc to send data out okay well let's calculate when that output is actually going to be sent clear out the output buffers to prepare for calling the IO brock's and then call all the i/o procs that are installed for this device as I mentioned that even a particular process can install more than one and you can have multiple processes sharing a device so there might be a number of i/o Crocs actually installed here once it's called all the i/o procs you've got say a handful of i/o procs that have filled out their buffers somebody's got to mix them to send them out into the output stream that's when core audio comes along and actually mixes all those io proc buffers together and then it sends it out to the card and loops back around so it spends its entire life time just gathering the input clearing the buffers getting the calling I approximant sending the data out so let's look at some code so this is the basic idea if you're a carbon CFM app you've got a load quality of ICF bundle karate is not available from CFM so there's some good sample code on the web and our sample code site and are actually in the carbon live SDK as well about how to call CFM or how we call ma KO routines from CFM once you've got access to the core audio system you can make some calls together device information you can set up the device properties the way you want them make sure the buffer size is correct and everything you add in your i/o proc and then you start the device and as soon as you start the device it starts calling your IO proc asking for DES so a brief diversion into the bundle api's if you have a URL say to the core audio bundle and this applies to any framework bundle you can get a reference for the bundle using CF bundle create you load the executable for that bundle to make sure it's in memory then you can get a function pointer for in this case some non-existent CA function name is the name of the function you get a function pointer for that using CF bundle get function pointer for name hardness what that does once you've got access to that API then you need to start calling them so you can call audio hardware get properly and in this case we're asking it for the default output device and karate oh guys recommend you actually use the default output device unless you have a specific reason not to if you want to actually look at the api's and query for the different output devices you can but this one will real easy way to just tell you okay what's the basic output device that I need to use this will give you an output device ID from there you can get and set some properties on it as I mentioned before you could get the configuration for the stream and things in this case all we need to do is we just want to say we need K samples per buffer and each sample is a float so we set that buffer size in there I don't even remember what I used in my code then we have to install our i/o proc and the i/o proc is actually it's actually mostly input parameters the top two thirds there's the parameter list and as you can see you get a device ID so you can actually have the same proc installed on multiple devices so this will tell you which device is actually asking for data you get the timestamp for the up from the audio system to say here's what time it is now the input data and the input timestamp when that data was actually sampled then you have the ones that I've highlighted there that are more interesting for our discussion the output data the time when that data is actually going to be played and some client data that you could actually pass in when you install the i/o proc and then down there at the bottom I put just a real simple you know for each sample frame you know a frame being left and stereo whatever for each sample frame for each Channel neither the left channel the right channel fill in that output data buffer there once you've got your i/o proc installed all you have to do is start the device so you say start the device with that i/o proc a caveat here as soon as you call this it's going to start calling your i/o proc so beware make sure that you don't do this and then expect to be able to set up a few more structures or whatever for the i/o proc it's already going to call you so be ready for it so let's take a look at a simple demo here and my colleagues have voted this the most annoying demo at WWDC so I'll show you the simple tone demo so this is a simple cocoa app that wired up and not too long big plug for Coco here really easy stuff to play with good for prototyping and user interface [Laughter] [Music] sine waves you can also play with if you get them halfway out of phase [Music] so that's the nice version that one has nice simple octaves and everything let's run this one this one we can play a little bit more with some other things you learned in music theory class [Music] so all I'm doing here is simply got a KOCO app I've installed four different IO props one for each channel and the core audio is taken care of actually calling these back for each one in turn I'm simply generating the waveform on the fly sine waves square wave thought to fairly easy stuff we'll be posting the sample code in the next week probably so you can take a look doesn't work and how to how to use for audio get to those especially for those of you that work in cubes I was actually working on that app a little bit during Jeff's OpenGL earlybird session and people were leaving okay so to wrap this up real quick high-level you know we've talked about several different interfaces core audio and sound managers are great if you've got raw sound samples that you just want to throw out get out to the card to play them if you've got something more complicated like MIDI or mp3 it quick times a really easy way to get that up and running take a look at the API it's really simple if you want to do the heavy lifting you can but cook time Marty has done an awful lot of work to get that nice and neat so you might want to take a look at QuickTime API and coming up actually luckily there's still two audio sessions coming up in this very room at 3:30 we've got the audio processing in sequencing services and then for those of you that are more interested in some of the more powerful MIDI services that Mac os10 provides at five o'clock in this room we've got 210 MIDI on Mac OS 10 and then since this is a game session if you have games feedback for us if we're doing something well if we're not doing something well if there's something you'd like to see more of or less of what have you please come to the feedback forum in jae-won which is next door and give us our games feedback on games technologies and that's it for my part now I'll turn it over to Todd thank you he wasn't kidding about those demos was he hi my name's Tod Previn I'm the 3d graphics and de facto networking DTS engineer so I'm gonna recap one of the things that David wanted David slides went over which is what we're gonna learn about networking today I'm gonna go through bsd sockets in the most most detail including accessing it from both CFM and carbon and from from cocoa then I'm going to go through some simple setup and initialization code I'm also going to discuss some of the networking technologies that are available on 10 that are better suited to gaming as opposed to things like URL access which is more designed for mainstream applications let me go through some tips and tricks for networked gaming that's kind of a misnomer it's more of a it's more like a porting guide kind of give you some idea of how things map over to 10 so what do we have for networking on 10 well that first of all carbon there's carbon open transport as that name would imply open transport has been carbonized for OS 10 it's all there all the functionality that you need and that is one of the options you can use Nets Brocket open play we've gotten a lot of questions about this very recently and nets brachot and open play are now also available on Mac OS 10 and of course there's sockets which is available in the BSD layer so open transports available on 10 mainly as an easy path for existing applications to move over to Mac OS 10 from OS 8 and 9 again as I said all of the functionality of OS 9 is there so you don't have to worry about what what are the differences the whole thing has been taken and just pulled right over directly the open transport frameworks are all built on top of sockets now as opposed to whichever underlying layer they used on nine I don't know offhand this has been included for api compatibility only there's no additional functionality that you get from open transport on Mac OS 10 open transport uses threads to emulate any of the asynchronous mode stuff that was available on OS 9 you do a you do incur about a 10% performance hit for using open transport as opposed to using sockets directly and the protocol subset that is supported by open transport on 10 is much smaller than it was on 9 supporting only tcp/ip DDP IP and n n BP for appletalk open play net sprocket is a derivative Wilander but it's the evolution of net sprocket from traditional mac OS apple open sourced at some time back and since then it's kind of developed into two different areas that being open play and that's Brocket itself they're both open source api's they are now cross-platform available Mac and Windows I believe there was a Linux UNIX version that was supposed to be coming but I couldn't find much information on that and it also has been carbonized for Mac OS 10 so with Nets bracha what they did was they made it the high level interface that is now instead of built on top of open transport I believe is what Nets Brockie used to be based on it now sits on top of their own API which is open plain which I'll discuss in just a few minutes it does maintain most of the api compatibility with net sprocket although as i understand are some there are some differences between the two no new documentation is available for net sprocket but you can still use the won 7-3 I believe is the current version of Nets bracket documentation that is available that is still the most current so what exactly is open play open play is the low level interface that they've developed for for use on both Windows and Macintosh it's sort of akin to sprockets or rock excuse me sort of akin to sockets in that it doesn't have a lot of there's not a lot of one of these days I'll think of the words that I'm trying to come up with here it's it's it's fairly streamlined fairly simple and there's there's just not a lot there's not a lot to it as far as being overly friendly with a user interface they left most of that functionality up to Nets Brocket it's been called a network module manager so what exactly is a network module manager it's a protocol manager you tell it which protocols you want to use and and what you want to do with them it sets them up and then you can access them either directly through the open play calls or you can go through the high level net sprocket interface and access them that way so it provides three basic services which is configuration data transfer and enumeration now in the documentation it says it also provides human interface and miscellaneous functions but neither one of those I could find a whole lot of information on I think the user the human interface they're referring to was net sprocket but again couldn't find much out on that configuration wise just as I said it'll set up the protocol stacks for you you can do all your initialization right through open play just as you can through sockets data transfer it's what communicates with the drivers with all the network drivers sends it down to the hardware and spits it out on the wire an enumeration it will go through all of the available network interfaces including any sort of serial dial-up or Ethernet interfaces it will do numerate them for you so you can select whichever one you want to use this is kind of a graphical representation of how open play and nets Brockett function together with the high level interface sitting on top of a the network module manager and the network module manager calling down into the various various protocol stacks and and device interfaces that are available there's a little more information on on open play but URL is for apples open source open source website you can access it right there there is a complete set of documentation well ok not exactly complete but there is a set of documentation that goes along with open play it's it is really downloadable right now I believe the version is 2.0 a or something like that is the most recent one that's been posted up there and if there is there are two sample apps I believe mini play and mini test are the two apps that I saw in there that I was that that I was able to look at they again it's all been carbonized so they should all just build and compile right out of the box this is gonna be the real meat of our discussion here which is BSD sockets it is the standard UNIX networking API it's available across every implementation of Unix out there the interface itself has not changed in many many years however there have been been some super sets of it made for for like Windows and I thought SGI and with I ryx had another had another implementation of sockets that had more of a higher-level user interface to it then then straight sockets did but one of the key things about sockets is that all of the functions are synchronous they are blocking calls so anytime you actually call one of these things you're gonna have to wait until it completes as you'll see you later on with certain functions such as DNS when you do get hosts by name or get host by address you're gonna sit there waiting for a while if you've got some slow DNS servers in your pathway this is sort of how a socket application will look from a high level both the server and client will both call socket to create sockets for themselves sockets are just file descriptors is really all they are across any operating system so they're pretty much going to function the same way any anytime your act some sockets for a server it's important to call bind what mine does is bind takes a local the local address of the server and associates it with that socket so that any incoming connections to that server will say oh here's the server we're looking for here's the address I want you're the one and that's how they that's how a client-server can establish an association the server woman call listen as listen is what sets up the socket so that will accept incoming connections and that it would be on the client side the reference for that would be connect where the client actually goes out over the network and says alright this is the server I'm looking for where are you the server that's now in listen mode will hear hear that incoming connection and and then provided of course that the the connection is is correct and the server is set up to handle a connection from that particular client it will call accept accept basically tells the server that yes or excuse me accept is the service way of saying alright you client you're good to go I'll accept your connection accept will create as it's returned value it creates a new socket in a connection-oriented mode it it would actually create a new socket that is the that is now associated with that with that end of the with with the incoming clients socket so you've now got a endpoint to endpoint connection once you've established that association between those two sockets you're now free to send and receive data back and forth between client and server when you're done once once all the data has been transmitted that needs to be transmitted both sides call close to to get rid of the socket or excuse me to close the that will close the connection that will not destroy the socket yeah how you do that I'll show you in a moment so how we can initialize the socket interface well CFM Carbon applications are going to need to call are going to need to load the system framework the sockets framework through CF bundle David showed you had to do that in the sound portion I've also included a URL up here at the bottom of the page that if you look for the sample call ma Co framework that will tell you how to a CF bundle or scuse me load amok Oh framework from a carbon CFM application ma Co carbon applications all you have to do is include the system framework and it's right in there if you wanted access to the actual if you wanted to see what the header files actually look like they're in the cysts subfolder of the system framework and there's Sakai Oh socket SH and suck at VAR h are the three header files that you're going to want to look at mainly if you're if you're curious Co Co applications have two options naturally you can use the NS sockets framework or you can load the system framework and access them directly as I just described either way works just as well the NS sockets framework I believe is obviously set up for an objective-c interface so it's it's really six of one half dozen together depending on which one you want to use so creating sockets as I mentioned before each both servers and clients will need to create sockets in order to communicate over the network per connection you you need one socket now with with multi casting multihoming and a couple of the other couple of things like UDP for instance you can actually because it's a connectionless protocol UDP is is capable of sending messages to different hosts on the network for instance of the UDP if you had four servers out there and one client if all of them were using UDP the client would be able to send a message to server one server to server three and server flow without establishing a connection in between all of them because UDP is a connectionless protocol uses what's called a Datagram that includes in it the core as a parameter to the send function or send to function it includes the address of the server that you want to talk to or the the destination that you want to talk to so every time you send a message you're telling okay I'm sending this one to server one now I'm gonna send this one to server for that's already included right there in the in the sent to function the functions of the the socket function returns the socket descriptor as as I mentioned earlier the sockets descriptor is just a file descriptor if you really look at it it's just an int so very simple datatype so how you gonna create sockets this is a little this code here can be you you can use this code directly and you'll create sockets of various types the top one is a sock stream that's used with the protocol tcp which will create a connection-oriented data stream oriented socket these are useful for things like doing file transfers if you're going to send contiguous blocks of data so if you wanted to do if you wanted to stream if you wanted to stream audio out you probably want to use TCP tcp is a reliable protocol which means it does it's error checking and correcting it will do resends there is a little caveat to that tcp is under no obligation whatsoever to let you know that it's doing resent or let you know that it's dropped packets so what does that mean well you can be sending your data happily to a TCP socket and it will be humming along just fine the other end won't be receiving any of it you won't know about it and neither will they all they see is no more data is coming through TCP will just stop that's it it's all you get so there's really no way to to make tcp/ip or if should be TCP tell you that it's it's now doing error checking and correcting and trying to reestablish its connection there's no there's no functionality for that whatsoever which means it can be kind of dangerous to use if you if you have real time critical data so what's your option UDP UDP is connectionless but it is unreliable what you have to do is implement a reliability protocol on top of UDP fairly easy to do all you have to do is as you're sending messages back and forth you just make sure that both the client and server have some method of saying all right I send a message did you get it client responds I got the message so and then you just kind of loop back and forth on that whenever one of them does not receive a message all you have to do is say alright resend and yuri transmit the same data does require a little bit of work although most of the time if you're if you're talking about the network gaming or where you really need to be sending data back and forth it doesn't matter if you miss message five and you're now on message eleven message five is probably irrelevant out-of-date information anyway so there's no need to resend you drop it you interpolate between where you were and where you are and you move on for instant the last thing is an ICMP which is Internet control message protocol you would use this for any sort of well Internet control message things like pings pings are all done through ICMP so establishing connections well the first thing you need is you need a an address and sockets defines the sock a DDR structure which has a name it's got a port and an address those are the three things that you need to establish the association that you need for a connection that applies to both TCP connection oriented and UDP connectionless associations generally speaking you're going to need the length - which is why you do the size of the address just for for the purposes of sending it to some of the some of the initialization and sending functions that sockets has you'll see int backlog that's used down there on the listen function where when the server calls listen on a particular socket it needs to know how many connections you want to queue before it starts dropping them if if you specify that to zero it will process connections as they come in there's only one problem with that in is that if you're processing a connection if you're in the middle of processing and connection then it's not going to be paying attention to what's going on on that socket so it connects you come in and it will just automatically drop so generally you want to set it to something like two or three if you have an extremely busy server you want to set that up higher so it will actually queue the connections up and you don't lose any of them bind right above it what bind does is is it will associate the socket address that you've specified with the socket so for a server what does that mean as I said before it means that now the server has an idea of who it is so when there's connections coming in to that specific address the server knows that it's referring to itself and will then continue to call it it will it will continue to accept incoming connections because it now has some identity now you can call bind on the client-side that's useful for a couple of different things if you have a UDP connection that's connection it's it's UDP connectionless association on a client-side it's kind of strange because a UDP socket will accept input from anywhere so some random guy on the net sends a package out that happens to have or sends a Datagram out that happens to have your address in it because they erroneously specified it unless you're locked in your your clients gonna gonna pick that up and it's gonna read that data in society prevent that from happening what you call bind what bind does in the client-side is it says all right I'm only going to use the socket to transmit data to and from this address it will not accept data from anywhere else it will only accept datagrams from the address that you specify this does not mean that you cannot reassociate that socket later if you need if if for instance your client wants to communicate with a couple of different servers there's a little more work involved you have to actually shut down the connection and destroy the association recreate your socket and then continue to send or continue to communicate with the new server but it can be done so again onto the accept function this is only used on the server side it can be used when you're talking about a client-server architecture if you have a client that is also a server you can use accept although it's usually easier if you're doing client-server to just go peer-to-peer as opposed to having the the two separation there if you don't call accept excuse me if you call accept from a server it will create a new socket so now you're gonna have a wider array what you would end up with is you'd end up with a whole bunch of sockets that are associated with the same client so you'd kind of get this criss-crossed network that ends up being you'd end up with peer-to-peer at that point so sockets she's me except takes the sockets do you want to accept the incoming the incoming connection on it accepts it also takes the address and the address link it will have that information because when the server receives the incoming connection from the client the connection the the incoming address from the client is actually transmitted to the server that's where you will get that information from now when the accept function returns it does return a new socket if you want to communicate with the client on the other end of that socket that is the that is the socket that you use the listening socket on the server you shouldn't be transmitting more data on because it's sitting there just waiting for incoming connections so here we'll go through the connect function this is again for connection oriented for UDP it's slightly different the socket that you pass in there is there is the clients local socket the address that you pass in is the address that you want to connect to not the address of the client I suppose you could connect to yourself if you wanted to do a loopback but yeah that's that would be entirely application-specific you also send it as I mentioned earlier the address link this is one of those functions that requires that needs to know how much data you're actually passing into it connect only returns Connect does not return anything error codes it will return zero if if no errors you can use last error I believe will give you the last socket error that occurred you have to be careful that because that's not updated it's only updated when an error occurs so if you call get last error if when you when a function returns zero you'll get the last error that actually occurred what a little caveats about connect is that connect assigns the local address if you don't call bind normally that's fine unless you wanted to assign your client a different address there wouldn't be much of a problem with that the reason that it doesn't do this I believe is for when you want it to do dynamic address updating that's getting way way off off-topic that's not something I want to go into so sending receive data you've got a couple of different functions for connection oriented sockets you'll be using send and receive there's also two other functions that are sent to and receive from those are mainly used with UDP because they one of their parameters is the address that you want to communicate to or from with a connection-oriented socket both functions perform identically there's no there's no difference you're simply passing in an address but you've already got a connection the connections establish is already associated with that address so the the extra input is just discarded you can use both of them synonymously with a connection-oriented socket tcp streaming which is usually not a bad idea if you're gonna be changing protocols on the fly she'd probably use send to and receive from there's slightly more overhead involved with them but it's not significant enough to worry about so as parameters send takes the socket that you want to send on for a client that would be the only socket that it has for a server that would be the socket you know for a for a streaming server for a TCP server that will be the socket that is associated with a client you want to communicate with if you have a wide array of clients and you want to broadcast a message to all of them using TCP you'd have to right through each socket and send the same data on each socket before you could move on it also takes above a pointer to a buffer which is just a buffer of bytes that it will read in and splatter out on the network bytes is the byte count that's how many that's how many bytes of data are in the buffer at the time and you just you pass that along along with any flags that you might have flags are not terribly important they really only if you're gonna be sending things like out of bow out of band data which is beyond the scope of this discussion is is flags really important most of the time you can just pass zero receive on the other hand is the sockets you want to receive the data on again for a server you're gonna have to iterate through all of the all of the sockets that you've created with accept in order to get all of the data that's incoming from the clients which would be kind of slow this is why it's recommended that for for real time like games for real-time data like that you want to use UDP it gives the server one socket that it has to read data in on granted the buffer is large but you can read data in a lot faster from a single large buffer than you can from 300 buffers having to loop through each one and call the same data input routines every time receive takes the same number of parameters widths and the same kinds of parameters as as send the receive buffer however is not a pointer to the buffer that the data is in it is a pointer to the buffer that the data will be transferred into if you do not have a data buffer that is large enough to accommodate the data this function will fail it will come back with the forget the the error message that it fails with but it fails with with something similar to your data buffers not big enough so reallocate it to get around that you can do a if you pass in as one of the flags is one of the flags to receive I think you can pass in message peak which will tell you exactly how much data is in the buffer so you can do that before you read it in every time and allocate your buffer dynamically like that so shutdown and cleanup all these functions take will close close just shuts down the socket that's all it does and it just except it only takes as a parameter the the socket that you want to close very simple shut down on the other hand is a little more in-depth shut down with shut down you can tell it what you want to do with any residual data that's remaining on the send to receive buffers a lot of times you'll want to flush and clear any residual data you want to get those last few bytes in or out so you want to use shut down a lot of times the extra control that that shutdown does offer is quite useful and I actually will call I call shut down in my network applications more more often than I just simply call closed your port number is going to be assigned based on on your address so but both of them are actually in a clear port once the socket it once the socket is closed or shut down that will that will free the port so a few little tips and tricks for Mac OS 10 for open transport applications what can you do I know there's a lot of existing open transport applications out there so there's there's two options you can use the OT shim that's there it does work but your other option is to port it directly sockets as I said ot on ten sits right on top of the sockets layer and you do incur about a 10 percent performance hit to use OT as opposed to going directly to sockets I'm gonna go through a couple of slides in a moment that will show you how ot maps maps to sockets if in fact you do want to port your OT app to two sockets directly for Windows UNIX applications UNIX apps are going to be pretty much a straightforward port I don't think there's any semantic differences between our implementation of sockets and the standard UNIX implementation windsock applications there are some notable differences which I will which I will go through momentarily and there's also direct play applications which aren't going to really translate across to anything give you some suggestions as to where you might want to look so using your to Sheamus again the easy way onto nine or from eight and nine onto ten reporting two sockets would be my my recommendation so how are you going to do that well here's some of the on the left-hand side of this of this slide you'll see some of the some of the open transport functions on the right you'll see they're they're sort of a brother over that it lives in sockets land so T end point that's just a socket as far as as far as we're concerned here bind and connect map over to binding connect of four sockets for an active ot connection now I'm not exactly sure what the difference is I'm not really an OT guy but these two obviously map pretty well right over - right / two sockets so for sending data again there's there's an extra sin which is send message which is Datagram oriented that's a function call that I'm not too familiar with I tend to stick to send and send to myself but I'm assuming that they're going to be fairly simple and probably something more similar to send to then then it would be to send that is they take the address parameter and I'll take a probably the length of the address I would assume and receiving it's the same way so disconnecting and cleaning up as I said you can use shut down what are interesting things about this is the set saw cop so linger what exactly does that do setting that sock option s olinger means that the socket is going to stick around until you actively close it and until any remaining data is read or received from that socket mr. Stahl it means as opposed to if you simply called shut down or or close you can actually just kill it right there and not read any of the data in so I mentioned before know something about synchronous operations these two functions get hosts by name and get hosts by address they're both blocking functions which means that they're going to stall until they actually get a return there's a way around that which is by placing these in their own threads and letting a thread go off and wait however long it wants to while you continue with your application that's the recommended way of emulating async mode on Mac OS 10 or on any socket supplementation for that matter another point to note about these is you can't cancel them so once you go in there's no going back you gotta wait till it finishes so with direct play direct play is obviously specific to Windows directly there's no there's no other API like it out there safe or something like a net sprocket that is kind of the high same high level type API you can port direct play to net sprocket I'll be perfectly honest with you I have never looked into doing that so I don't know how much work would be involved but I would assume that it's probably not going to be the easiest thing to do but it is an option if you're willing to go down that path windsock is much more interesting windsock mostly maps onto sockets directly by mostly I mean that there are some functions in windsock that are specific to where to windsock itself so what are the differences sockets has no a psychic or asynchronous functionality I just mentioned before how to how to deal with that little caveat there are also no predefined startup or shutdown routines because they're not necessary in Mac OS 10 or on any sockets implementation aside from Windows I believe like WS a startup W say cleanup W say async select is another one that's used a lot to generate the asynchronous message modes that windsock uses none of these things are available because they are they are not part of the standard sockets excuse me standard socket API which is the standard cross-platform sockets API they are only available on on Windows any functions that are prefixed by the WUSA those are all specific to to Windows itself so if you're looking for cross-platform compatibility those are things that you'll want to try to use less the last bullet on this slide is is kind of kind of interesting Windows defines a data type of socket all uppercase the standard socket data type is just an integer so it's file descriptor so why does Windows redefine the socket that's a good question because I don't rightly know I do know that it causes a lot of problems oke because when I was first writing network applications I was using the socket data type very heavily until I found out that you can just cast an int to the same thing and it still works yet I don't have to go through the effort of recoding every time I move my windows code to another platform so just one of those little interesting tidbits I stay away from the socket definition so kind of as a summary I went through the networking technologies that are available on Mac OS 10 those include open transport which is fully carbonized open plain Nets Brocket again which are which are carbonized and are also open source and I also went through sockets in some in relative detail I went through the initialization of it and how to set up your sockets application and kind of give you a general idea of how a client-server application is going to work went through some of the little little tips tricks and caveats for networking on Mac OS 10 and bringing your network applications to OS 10 and one of the more important things was illustrating the differences between an API such as windsock that is specific to the Windows platform and the sockets API which is a standard UNIX definition so for a little more information on networking there's there's two series of books that I would highly recommend to anybody who's very interested in networking the top one is UNIX network programming by Stevens excellent series of books the first one the Volume one goes into a lot of detail about how the networking subsystem operates on UNIX it goes into the whole basis for for tcp/ip and there's a lot of great information in it volume 2 is more about inter process communication which is using using sockets for using sockets as pipes for talking between applications on the same server or on different servers the tcp/ip series it's called internet working with tcp/ip by comer is another great series on networking the first one is the principles and practices the second one is anybody now I don't remember I should remember what two and three are but they're really good I know that because I own them all there's also some things that some mailing lists that one escape me for a moment there's three-minute through mailing lists in particular at Apple that are they're maintained on at Apple that you'll want to look at if you're interested more networking stuff the UM play developers list that one obviously relates specifically to open play and that open source project not terribly active but it seems to be generating more interest now the open transport developers list am not sure how active that is as I said I'm not really an open transport guy but from what I understand it's still pretty busy and then there's also the Darwin developers list make sure you have a lot of room on your hard drive if you're downloading this list because it is busy probably on the order of 100 messages a day but that's where a lot of the kernel level networking stuff gets discussed if you really want to delve that deeply into it so my roadmap well it's not really a roadmap because it refers to everything that happened in the beginning of the week but I put it up here just for anybody who wants to reference the sessions once the DVDs finally come out 300 was the networking overview you might recognize some of the content from one or two of my slides from the 300 session it kind of we kind of had the same things there extensible kernel networking services again that's gonna be more for people who are interested in the Darwin development stuff and the kernel level stuff networking configuration mobility that's more user level network configuration as opposed to programmatic network configuration network services location I don't remember what that one was about no check it out on the DVD somebody let me know and AFP is 3.0 and Apple shares just that say FP on on Mac OS 10 you
