Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > TCP communication API?

TCP communication API?
Thread Tools
Thinine
Mac Elite
Join Date: Jul 2002
Status: Offline
Reply With Quote
Feb 23, 2005, 02:40 AM
 
I've been researching the network API's available in OS X and have found that none of them really seem to deal with raw TCP communications. Unless I'm missing something, CFNetwork is as close as I can get without resorting to BSD sockets, but doesn't offer the sort of granularity I need. Can someone point out some good examples of TCP communication is OS X? I really don't want to have to learn sockets.
     
ideasculptor
Forum Regular
Join Date: Dec 2004
Status: Offline
Reply With Quote
Feb 23, 2005, 03:11 AM
 
Why don't you want to have to learn sockets? Never mind that they are easy enough to learn and use, how do you expect to be able to do raw TCP communication without doing, well, raw TCP communication.

You read, you write, you close. It isn't exactly rocket science. The only marginally complicated thing is establishing connections. Sure, tuning your TCP app can be where the real magic lies, which is exactly why you don't want to use a high level api which doesn't expose the many options that are available to a knowledgable sockets programmer. Working with sockets closely resembles reading and writing to a file. What is there to fear?

Besides, sockets are the very foundation of network programming, and network programming is becoming the foundation of modern software engineering. It is hard to think of a recently built application that doesn't interact with a network. Not wanting to learn sockets is like a CS major not wanting to learn C or assembler. Even if you rarely use them, the knowledge you gain about the way the computer and network work is invaluable. You'll be able to make far more effective and efficient use of higher level APIs if you understand what is happening lower down.

google up a webpage about sockets programming and you should have a working client and server framework in just a couple of hours.

--sam
     
Thinine  (op)
Mac Elite
Join Date: Jul 2002
Status: Offline
Reply With Quote
Feb 23, 2005, 03:22 AM
 
I know, and you're probably right. I was just hoping to be able to put together a simpler program and then go back and optimize if the performance wasn't what I wanted. Also, this will be my first experience in network programming, so I was hoping to lessen the learning curve.
     
ideasculptor
Forum Regular
Join Date: Dec 2004
Status: Offline
Reply With Quote
Feb 23, 2005, 04:55 AM
 
Originally posted by Thinine:
I know, and you're probably right. I was just hoping to be able to put together a simpler program and then go back and optimize if the performance wasn't what I wanted. Also, this will be my first experience in network programming, so I was hoping to lessen the learning curve.
You won't get much simpler than BSD sockets. The only difficulty is in establishing a connection (whether on the server or the client end). Once you have a socket descriptor, it works just like a file descriptor. To read from it, you pass an array of chars to the read() function and to write to it, you pass an array of chars to the write() function. If you read or write -1 bytes, the socket was closed. When you are done, call close() on the fd. Pretty damn simple. The only minor complexity is that calling write(fd, buf, numBytes) doesn't actually guarantee that you will write numBytes bytes. Instead, you must check how many bytes were actually written (the return value) and if not all bytes were written, call write again with the remaining bytes. Keep doing this until there are no more bytes left. The same goes for read. Asking to read 312 bytes won't necessarily return 312 bytes. It might return 256, leaving you to call read again, this time asking for 312-256 bytes.

Here are some hints. Man pages should fill out the details enough to get code written. To create a socket, call the socket() function (man socket). For a TCP socket, you want to create an AF_INET socket of type SOCK_STREAM

Once you have a socket, you need to do one of two things. If you are a server, you need to bind to an address/port combination by calling bind (man bind). Once you have bound to a port, you need to look for incoming connections. Most folks use the accept function (man accept) which returns a new socket descriptor every time a connection is established. accept() blocks until a connection is received, so you can just sit in a loop on accept, and every time accept() returns, create a thread, pass it the new socket descriptor, and then call accept() again. The thread can then call read, write, and close on the socket.

If you are establishing a client socket, instead of calling bind and accept, call connect() (man connect). That will connect you to a remote socket (which can be on the same machine). Once you have successfully connected, you can read and write to your hearts content, just like you would with a file descriptor.

Don't forget to close your sockets.

With those 7 functions, you can build a complete client or server. If you want a general overview of tcp networking, 'man tcp' will get you started. level 4 man pages on 'inet' are also useful. Type 'man 4 inet' at the terminal. It describes the sockaddr structure you need to call connect and bind.

One last thing. If you are going to be putting anything other than ascii text on the wire, you need to be aware of the fact that some computer architectures store the bytes for multiple byte data types in a different order. This means that sending an int from a mac to an x86 machine will do bad things to the value of the int. To get around this, there is a standard byte order for networks. All applications must put multiple-byte primitives into network order before sending them and then convert them to host order after reading them. The functions to do this are htons, htonl (host to network short, host to network long) and ntohs and ntohl (network to host short and network to host long).

In an ideal world, you'd send a single int like this

/* start code */

int myInt = 1;
int bytesSent = write(fd, &myInt, sizeof(int));

/* end code */

In reality, you must do this:

/* start code */

int myInt = 1;
int netInt = htonl(myInt);
int bytesSend = write(fd, &netInt, sizeof(int));

/* end code */

On the receive side, you'd need to call ntohl on the value read from the socket. There, you should now be thoroughly confused and ready to read a more in depth web page on the functionality of sockets. Enjoy.

--sam
     
Angus_D
Addicted to MacNN
Join Date: Mar 2000
Location: London, UK
Status: Offline
Reply With Quote
Feb 23, 2005, 10:52 AM
 
CFSocket might make it easier for you to deal with interacting with your run loop, however (otherwise you'll have to spin off your own thread and deal with the inter-thread communication yourself).
     
smeger
Mac Elite
Join Date: Sep 2000
Location: Tempe, AZ
Status: Offline
Reply With Quote
Feb 23, 2005, 02:55 PM
 
You might want to check out Chicken of the VNC's networking code - it's some pretty basic socket-based TCP wrapped in Cocoa. I think the appropriate source is in RFBConnection.m.

Basically, it opens a connection, registers an objective-C instance method to be called when data comes in, sends some stuff periodically, and when finished, closes the connection. Nice'n'simple.
Geekspiff - generating spiffdiddlee software since before you began paying attention.
     
Samad
Fresh-Faced Recruit
Join Date: Nov 2001
Location: home
Status: Offline
Reply With Quote
Feb 23, 2005, 10:39 PM
 
If you really want to do diehard sockets programming, check out Unix Network Programming, Vol 1 by W. Richard Stevens. When I say "check out," I mean that literally, like from a library. This book is expensive if you buy it. If you're a student, you'll probably find it in your university's computer science stacks.
     
joltguy
Mac Enthusiast
Join Date: May 2001
Location: 127.0.0.1
Status: Offline
Reply With Quote
Feb 28, 2005, 01:18 PM
 
Steven Frank (of Panic fame) developed an open source library called SmallSockets. From the project page:
A lightweight Objective-C wrapper for BSD sockets on Mac OS X. The idea is to present an Obj-C interface to sockets in the lightest way possible, not requiring any extra libraries, frameworks, or files than what is supplied on the Mac OS X Dev CD.
I've never used it, but it sounds like what you're looking for:
http://sourceforge.net/projects/smallsockets/
     
   
 
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Top
Privacy Policy
All times are GMT -4. The time now is 02:22 PM.
All contents of these forums © 1995-2017 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.8 © 2000-2017, Jelsoft Enterprises Ltd.,