Welcome to Soft32 Forums!
FAQFAQ    SearchSearch      ProfileProfile    Private MessagesPrivate Messages   Log inLog in

Sockets in Cocoa

 
   Soft32 Home -> Mac -> Programmer Help RSS
Next:  TestTrack and Tiger; bug tracking app alternative..  
Author Message
Ulrich Hobelmann

External


Since: Dec 30, 2005
Posts: 90



(Msg. 1) Posted: Sat Jun 18, 2005 12:13 pm
Post subject: Sockets in Cocoa
Archived from groups: comp>sys>mac>programmer>help (more info?)

Hi, I'm kind of lost in between the sockets.
There's tons of connection classes, Ports, Handles, Protocols etc....

I just want to open a TCP connection to some server and be able to
send and receive data (i.e. cstrings or bytes) to it. A pipe
would be ok too, so I can talk to a local task.

My futile attempt included creating a NSSocketPort
(initRemoteWithTCPPort:21 host:@"localhost"), but the socket (file
destriptor is -1 (error??). The documentation says, the socket
only connects when data is sent. Ok.

So I create an NSFileHandle (initWithFileDescriptor:), register
for notifications, call waitForDataInBackgroundAndNotify on the
file handle and wait. But now the whole thing blows up, I guess
because the file handle wasn't even valid after all.

So: how DO I create a simple socket connection? How do I get
notified when data is there and send stuff back? The context is a
Cocoa GUI program (for now just textfield, send button, and
message field for server responses).

--
Don't let school interfere with your education. -- Mark Twain
Back to top
Login to vote
Sherm Pendley

External


Since: Jun 10, 2005
Posts: 63



(Msg. 2) Posted: Sat Jun 18, 2005 12:13 pm
Post subject: Re: Sockets in Cocoa [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Ulrich Hobelmann <u.hobelmann.RemoveThis@web.de> writes:

> Hi, I'm kind of lost in between the sockets.
> There's tons of connection classes, Ports, Handles, Protocols etc....

FWIW, Objective-C Protocols have *nothing* to do with networking.

> I just want to open a TCP connection to some server and be able to
> send and receive data (i.e. cstrings or bytes) to it. A pipe would be
> ok too, so I can talk to a local task.
>
> My futile attempt included creating a NSSocketPort

Stop. NSPort and its descendants are used for sending Mach messages.
NSSocketPort is for sending Mach messages over BSD socket, not for
sending arbitrary network traffic.

> So I create an NSFileHandle (initWithFileDescriptor:), register for
> notifications, call waitForDataInBackgroundAndNotify on the file
> handle and wait. But now the whole thing blows up, I guess because
> the file handle wasn't even valid after all.

Now you're on the right track. How did you create the file descriptor
you passed to the initializer? For socket communications, you should be
creating it with the socket() function - "man socket" for details.

sherm--
Back to top
Login to vote
Michael Ash

External


Since: Jan 18, 2005
Posts: 1073



(Msg. 3) Posted: Sat Jun 18, 2005 12:13 pm
Post subject: Re: Sockets in Cocoa [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Ulrich Hobelmann <u.hobelmann.RemoveThis@web.de> wrote:
> Hi, I'm kind of lost in between the sockets.
> There's tons of connection classes, Ports, Handles, Protocols etc....
>
> I just want to open a TCP connection to some server and be able to
> send and receive data (i.e. cstrings or bytes) to it. A pipe
> would be ok too, so I can talk to a local task.
>
> My futile attempt included creating a NSSocketPort
> (initRemoteWithTCPPort:21 host:@"localhost"), but the socket (file
> destriptor is -1 (error??). The documentation says, the socket
> only connects when data is sent. Ok.

Is port 21 open on localhost?

> So I create an NSFileHandle (initWithFileDescriptor:), register
> for notifications, call waitForDataInBackgroundAndNotify on the
> file handle and wait. But now the whole thing blows up, I guess
> because the file handle wasn't even valid after all.
>
> So: how DO I create a simple socket connection? How do I get
> notified when data is there and send stuff back? The context is a
> Cocoa GUI program (for now just textfield, send button, and
> message field for server responses).

As stated in another post, NSSocketPort is not meant for this kind of
thing. I've heard of people using it, so it's possible to make it work,
but it's really not recommended.

If you don't need to support 10.2 and under (and you really shouldn't),
then check out the NSStream APIs. They're very nice for sockets work if
you want to connect to a remote port, and initiating the connection is
simple.

If you want your code to be a server and listen for a connection, then you
can't use NSStream directly. I believe the most direct path is to use
CFSocket to listen for connections, then create a CFStream from that, and
CFStream is toll-free bridged to NSStream.

There are also plenty of non-Cocoa alternatives, of course. Plain BSD
sockets is an obvious choice, and there's also a fairly wide selection of
Objective-C sockets classes, with a list here:

http://www.cocoadev.com/index.pl?SocketClasses
Back to top
Login to vote
David Phillip Oster

External


Since: Jul 21, 2005
Posts: 1426



(Msg. 4) Posted: Sat Jun 18, 2005 4:20 pm
Post subject: Re: Sockets in Cocoa [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

In article <3his0aFhcqciU1.DeleteThis@individual.net>,
Ulrich Hobelmann <u.hobelmann.DeleteThis@web.de> wrote:

> Hi, I'm kind of lost in between the sockets.
> There's tons of connection classes, Ports, Handles, Protocols etc....
>
> I just want to open a TCP connection to some server and be able to
> send and receive data (i.e. cstrings or bytes) to it. A pipe
> would be ok too, so I can talk to a local task.

You are in luck. Apple just released sample code that demonstrates
how to do exactly what you are trying to do.

Look at:

http://developer.apple.com/samplecode/CocoaSOAP/CocoaSOAP.html

Pay particular attention to TCPServer.m and SOAPClient.m (which
depends heavily on NSURLResponse to actually read the data.

Note that this example gives the source code for a miniature, but functional,
http server. This does do SOAP, but there is an easier way to do SOAP with
Macintosh.

this may also be useful.

http://developer.apple.com/samplecode/XcodeClientServer/XcodeClientServer.html

Of course, if you can use SOAP or XML-RPC, Apple already provides an
appleEvent bridge, so just by changing the destination from another
program on your local machine, to one on a remote machine, AESend()
will take care of marshalling your arguments and unmarshalling the
return value.

See:

http://developer.apple.com/documentation/AppleScript/Conceptual/soapXMLRPC/

The web page is Carbon, but the translation to Cocoa is obvious.


If all you need is SMTP client support, NSMailDelivery is even easier:

<file:///Developer/ADC%20Reference%20Library/documentation/AppleApplications/Reference/MessageFrameworkReference/Classes/NSMailDelivery/index.html>

Note that URL is to documentation that is already on your machine.

There is a trick to getting NSMailDelivery to work: you must explicitly add
Message.framework to your project, your program will mysteriously do nothing.
Unlike most of the Cocoa frameworks, it isn't inside the Cocoa umbrella, so
you don't get it by default.

Also, don't forget that libcurl is available on Mac OS:
<http://curl.oc1.mirrors.redwire.net/>

--
David Phillip Oster
Back to top
Login to vote
Ulrich Hobelmann

External


Since: Dec 30, 2005
Posts: 90



(Msg. 5) Posted: Sat Jun 18, 2005 5:39 pm
Post subject: Re: Sockets in Cocoa [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Sherm Pendley wrote:
> Ulrich Hobelmann <u.hobelmann RemoveThis @web.de> writes:
>
>
>>Hi, I'm kind of lost in between the sockets.
>>There's tons of connection classes, Ports, Handles, Protocols etc....
>
>
> FWIW, Objective-C Protocols have *nothing* to do with networking.

Oh yeah, I know that Smile

It's just that there are some protocols that start with NSURL, so
I thought they might be relevant...

>>I just want to open a TCP connection to some server and be able to
>>send and receive data (i.e. cstrings or bytes) to it. A pipe would be
>>ok too, so I can talk to a local task.
>>
>>My futile attempt included creating a NSSocketPort
>
>
> Stop. NSPort and its descendants are used for sending Mach messages.
> NSSocketPort is for sending Mach messages over BSD socket, not for
> sending arbitrary network traffic.

"NSSocketPort can be used as an endpoint for distributed object
connections or raw messaging." says the documentation.

At least I thought the mighty Cocoa would have some builtin socket
functions, so I guessed it would be that one.

>>So I create an NSFileHandle (initWithFileDescriptor:), register for
>>notifications, call waitForDataInBackgroundAndNotify on the file
>>handle and wait. But now the whole thing blows up, I guess because
>>the file handle wasn't even valid after all.
>
>
> Now you're on the right track. How did you create the file descriptor
> you passed to the initializer? For socket communications, you should be
> creating it with the socket() function - "man socket" for details.

Yes, I actually have some socket() wrappers written in C. If
there are no socket functions in Cocoa, I'll use them and wrap
them in an NSFileHandle.

Thanks.

--
Don't let school interfere with your education. -- Mark Twain
Back to top
Login to vote
Ulrich Hobelmann

External


Since: Dec 30, 2005
Posts: 90



(Msg. 6) Posted: Sat Jun 18, 2005 5:46 pm
Post subject: Re: Sockets in Cocoa [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Michael Ash wrote:
> Is port 21 open on localhost?

Of course, that's why I chose it. Nicely readable text protocol Wink

> If you don't need to support 10.2 and under (and you really shouldn't),
> then check out the NSStream APIs. They're very nice for sockets work if
> you want to connect to a remote port, and initiating the connection is
> simple.
>
> If you want your code to be a server and listen for a connection, then you
> can't use NSStream directly. I believe the most direct path is to use
> CFSocket to listen for connections, then create a CFStream from that, and
> CFStream is toll-free bridged to NSStream.

I'll probably have an extra task running (written in C, portable
Unix code), so I'll just talk to it over a socket or pipe. My
main problem is how to integrate the stream into the Cocoa event
model (because select() would block and so I wouldn't respond to
Cocoa events anymore). Well, I hope the file handle or Stream
approach works; shouldn't be impossible... Smile

--
Don't let school interfere with your education. -- Mark Twain
Back to top
Login to vote
Michael Ash

External


Since: Jan 18, 2005
Posts: 1073



(Msg. 7) Posted: Sun Jun 19, 2005 12:24 am
Post subject: Re: Sockets in Cocoa [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Ulrich Hobelmann <u.hobelmann.DeleteThis@web.de> wrote:
> Michael Ash wrote:
>> Is port 21 open on localhost?
>
> Of course, that's why I chose it. Nicely readable text protocol Wink

It's the programming equivalent of asking the user if their computer is
plugged in. Silly, but the simple stuff ends up being the problem
surprisingly often.

>> If you don't need to support 10.2 and under (and you really shouldn't),
>> then check out the NSStream APIs. They're very nice for sockets work if
>> you want to connect to a remote port, and initiating the connection is
>> simple.
>>
>> If you want your code to be a server and listen for a connection, then you
>> can't use NSStream directly. I believe the most direct path is to use
>> CFSocket to listen for connections, then create a CFStream from that, and
>> CFStream is toll-free bridged to NSStream.
>
> I'll probably have an extra task running (written in C, portable
> Unix code), so I'll just talk to it over a socket or pipe. My
> main problem is how to integrate the stream into the Cocoa event
> model (because select() would block and so I wouldn't respond to
> Cocoa events anymore). Well, I hope the file handle or Stream
> approach works; shouldn't be impossible... Smile

NSFileHandle should do fine for integrating your socket into the runloop.
CFSocket is also good for that if you really want to use the BSD sockets
API everywhere possible.

You could also run your sockets stuff using select() in another thread if
you really want to keep everything nice and POSIXy.
Back to top
Login to vote
Ulrich Hobelmann

External


Since: Dec 30, 2005
Posts: 90



(Msg. 8) Posted: Sun Jun 19, 2005 9:30 am
Post subject: Re: Sockets in Cocoa [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Michael Ash wrote:
> NSFileHandle should do fine for integrating your socket into the runloop.
> CFSocket is also good for that if you really want to use the BSD sockets
> API everywhere possible.

Yes, works nicely Smile

> You could also run your sockets stuff using select() in another thread if
> you really want to keep everything nice and POSIXy.

Well, since it seems I have to call
waitForDataInBackgroundAndNotify again and again (and thus create
and kill threads all the time) I might actually roll my own there,
select()ing and posting notifications on my own... But for now
it's fine.

--
Don't let school interfere with your education. -- Mark Twain
Back to top
Login to vote
Matthew Barnes

External


Since: Jun 25, 2005
Posts: 1



(Msg. 9) Posted: Sat Jun 25, 2005 5:53 pm
Post subject: Re:Sockets in Cocoa [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

> Now you're on the right track. How did you create the file descriptor
> you passed to the initializer? For socket communications, you should
> be
> creating it with the socket() function - "man socket" for details.

Apparently, I have started out on the same track Ulrich did at the
beginning. I am writting a chat client for a not so known client
with a VERY basic protocol already set in place. At first, I was
reading Cocoa In a Nutshell and following the Networking chapter
pretty closely. Nothing really worked so now I'm reading through
Unix Network Programming.

I just got through going through the streams documentation on
Apple.com, but haven't gotten anything to work. Obviously I don't
have much experience with this, but figured it wouldn't be hard to
catch on since I wrote a client for the same protocol a month ago on
Windows.

After reading this thread, and looking up CFSocket, I don't think
that will work for me unless there's a way to connect to various
ports. Also, I think NSOutputStream isn't working because it isn't
using a raw socket. Like I said, I'm not experienced so what do I
know.

Should I just stick to socket() used in Unix Network Programming?

* posted via http://www.mymac.ws
* please report abuse to http://xinbox.com/mymac
Back to top
Login to vote
Chris Hanson

External


Since: Oct 30, 2005
Posts: 126



(Msg. 10) Posted: Sat Jun 25, 2005 5:53 pm
Post subject: Re: Sockets in Cocoa [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

On 2005-06-25 15:53:47 -0700,
matthew.b.horton RemoveThis @gmail-dot-com.no-spam.invalid (Matthew Barnes) said:

> After reading this thread, and looking up CFSocket, I don't think
> that will work for me unless there's a way to connect to various
> ports. Also, I think NSOutputStream isn't working because it isn't
> using a raw socket. Like I said, I'm not experienced so what do I
> know.

I'm not sure what you mean by "raw socket" here.

If you can require Panther or later, I strongly recommend you take
another look at NSInputStream and NSOutputStream for TCP
communications. It's very easy to use once you understand the way it
fits together.

Here's the 30-second summary, written off the top of my head:

(1) Use +[NSStream getStreamsToHost:port:inputStream:outputStream:] to
get an NSInputStream and an NSOutputStream to the server you want to
communicate with. Be sure to retain them, since they're returned to
you autoreleased. (After all, they come from a method that isn't an
alloc, copy, or retain method.)

(2) Set your controller object to be your input stream and output
stream's delegate. This means that it will get callbacks for events
that occur on each of the streams via its -stream:handleEvent: method.

(3) Schedule each stream in the current runloop in the default mode.
This means that your streams' operations will be asynchronous, and that
you don't need to worry much about them blocking execution of your
application as long as you handle the delegate callbacks appropriately.

(4) For your input stream, handle the following events in your
controller's -stream:handleEvent: method:
NSStreamEventHasBytesAvailable (only read when you get one of these,
and only read the number of bytes actually available - you can ask the
stream for this info), NSStreamEventEndEncountered (e.g. the other side
closed the connection), NSStreamEventErrorOccurred.

(5) For your output stream, handle the following events in your
controller's -stream:handleEvent: method: NSStreamEventOpenCompleted
(don't try to write before you get this),
NSStreamEventHasSpaceAvailable (write when you get one of these, and
don't write again until you get another one),
NSStreamEventErrorOccurred.

(6) Open your streams.

(6) When you're done, close your streams and release them.

There may be more you need to do, or I may have gotten the steps
slightly wrong; after all, this is off the top of my head. So check
the documentation here:
<http://developer.apple.com/documentation/Cocoa/Conceptual/Streams/index.html>

Fundamentally,

streams provide you with a callback-based system that you can use to
read and write network data asynchronously. It might be a little more
work than you're expecting if you were planning on working
synchronously (e.g. write something, read something, write something,
read something) since you'll have to implement a basic queuing system
and deal with incomplete reads and writes, but once you build some
basic infrastructure around it, it'll be very powerful. And it
integrates with Cocoa's run loop mechanism and uses the delegate
pattern, meaning you don't have to do learn a separate event-handing or
registration system.

-- Chris
Back to top
Login to vote
Geir-Tore Lindsve

External


Since: May 19, 2005
Posts: 5



(Msg. 11) Posted: Wed Jun 29, 2005 7:03 pm
Post subject: Re: Sockets in Cocoa [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

A little follow up on this issue.

In may, I set up a small game client which communicates with a server
by using NSInputStream and NSOutputStream. That works well, but now I
have decided to set it up for another "environment".

I'm planning to rewrite the game to be independent of that server. What
I then are planning are to give the user the choice of starting a game,
or connect to a existing game when the game opens. I guess that the
current use of NSInputStream/NSOutputStream works for connecting to a
existing game.

But how can I set up a game to wait for connections from another client
(which uses NSInputStream/NSOutputStream), and the set up
input/outputstreams to that client?

Any advice?
--
Mvh
Geir-Tore Lindsve
Back to top
Login to vote
Michael Ash

External


Since: Jan 18, 2005
Posts: 1073



(Msg. 12) Posted: Wed Jun 29, 2005 10:28 pm
Post subject: Re: Sockets in Cocoa [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Geir-Tore Lindsve <lindsveFJERN.TakeThisOut@bluezone.no> wrote:
>
> But how can I set up a game to wait for connections from another client
> (which uses NSInputStream/NSOutputStream), and the set up
> input/outputstreams to that client?

As you may have noticed, NSStream doesn't have any APIs to wait for a
connection, only to make a connection to somebody else who's waiting.

However, CFStream allows you to create a stream pair for an arbitrary
native socket, and CFStream and NSStream are bridged. This means that the
main issue is doing the whole listen-and-connect dance, because CFStream
expects you to have already done that. You could do that in a separate
thread using the standard POSIX APIs, or you could use CFSocket to handle
that phase, which has nice runloop integration.

So in summary, CFSocket to listen, CFStream once connected, and then cast
to NSStream and do what you have been doing.
Back to top
Login to vote
David Phillip Oster

External


Since: Jul 21, 2005
Posts: 1426



(Msg. 13) Posted: Wed Jun 29, 2005 10:32 pm
Post subject: Re: Sockets in Cocoa [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

In article <42c31abd$0$18648$14726298@news.sunsite.dk>,
Geir-Tore Lindsve <lindsveFJERN RemoveThis @bluezone.no> wrote:

> A little follow up on this issue.
>
> In may, I set up a small game client which communicates with a server
> by using NSInputStream and NSOutputStream. That works well, but now I
> have decided to set it up for another "environment".
>
> I'm planning to rewrite the game to be independent of that server. What
> I then are planning are to give the user the choice of starting a game,
> or connect to a existing game when the game opens. I guess that the
> current use of NSInputStream/NSOutputStream works for connecting to a
> existing game.
>
> But how can I set up a game to wait for connections from another client
> (which uses NSInputStream/NSOutputStream), and the set up
> input/outputstreams to that client?

<http://developer.apple.com/samplecode/Cocoa/idxNetworking-date.html>
has some good resources for you. Take a look at:

CocoaSOAP - Demonstrates implementing a SOAP client and server in Cocoa.
at the tcp/ip level, even includes the source code for a small http
server.

<http://developer.apple.com/documentation/Cocoa/Networking-date.html>
is also useful.

--
David Phillip Oster
Back to top
Login to vote
Geir-Tore Lindsve

External


Since: May 19, 2005
Posts: 5



(Msg. 14) Posted: Thu Jun 30, 2005 8:38 pm
Post subject: Re: Sockets in Cocoa [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

On 2005-06-30 10:28:49 +0200, Michael Ash <mike.DeleteThis@mikeash.com> said:

> Geir-Tore Lindsve <lindsveFJERN.DeleteThis@bluezone.no> wrote:
>>
>> But how can I set up a game to wait for connections from another client
>> (which uses NSInputStream/NSOutputStream), and the set up
>> input/outputstreams to that client?
>
> As you may have noticed, NSStream doesn't have any APIs to wait for a
> connection, only to make a connection to somebody else who's waiting.
>
> However, CFStream allows you to create a stream pair for an arbitrary
> native socket, and CFStream and NSStream are bridged. This means that
> the main issue is doing the whole listen-and-connect dance, because
> CFStream expects you to have already done that. You could do that in a
> separate thread using the standard POSIX APIs, or you could use
> CFSocket to handle that phase, which has nice runloop integration.
>
> So in summary, CFSocket to listen, CFStream once connected, and then
> cast to NSStream and do what you have been doing.

Thanks for the tip from both of you. I'll be looking into these.
--
Mvh
Geir-Tore Lindsve
Back to top
Login to vote
Display posts from previous:   
Related Topics:
I'm having problems with sockets - I've been playing with sockets, and I have a problem. When I try to create a socket port like this: incomingSocket ...

How to Specify port # in BSD Sockets? - I'm using BSD's open() to get my host's socket. The trouble is passing it a specific port -- when I try the app, it ret...

Threads, sockets, blocking calls - I have an old Classic Open Transport program that I'm trying to modernize with sockets. This program runs a server th...

#import questions with Cocoa/Cocoa.h and SMySql/SMySql.h - I am still new to Xcode, having come from using CodeWarrior, and am building the CocoaMySQL application from the sourc...

C++ in cocoa - Hello, I read various statements in google but... Is it now possible to use c++ in "traditional" obj-c coco...

[COCOA]have you ever seen this? - i wrote an application in cocoa-java(thank you for your help in my last thread)...it compiles without errors, but when...
       Soft32 Home -> Mac -> Programmer Help All times are: Pacific Time (US & Canada) (change)
Page 1 of 1

 
You can post new topics in this forum
You can reply to topics in this forum
You can edit your posts in this forum
You can delete your posts in this forum
You can vote in polls in this forum

Categories:
 Windows
 Linux
  Mac
 PDA


[ Contact us | Terms of Service/Privacy Policy ]