• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: TCP/IP Connections
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: TCP/IP Connections


  • Subject: Re: TCP/IP Connections
  • From: email@hidden
  • Date: Sun, 23 Dec 2001 17:55:12 +0100

Hi Chris,

That was what I was looking for!

I added my own category (only one method) for NSFileHandle and that was all. It works like a charm!

The only drawback I'm currently having is that it takes an extremely long amount of time for the connect() to timeout when you try to connect to a host that is down. I also couldn't find any ioctl command that would let me set the timeout. I know it's not a cocoa subject, but if anyone has an idea I would be happy to hear it.

For others who are interested in how I did this. Here is the code:

NSFileHandleSocketConnection.h:
---
#import <Foundation/Foundation.h>

@interface NSFileHandle (NSFileHandleSocketConnection)

+(id)fileHandleForConnectionToHost:(NSString*)hostname atPort:(unsigned short)port;

@end
---

NSFileHandleSocketConnection.m:
---
#import <netdb.h>
#import <netinet/in.h>
#import <sys/socket.h>
#import <unistd.h>
#import <fcntl.h>

#import "NSFileHandleSocketConnection.h"

@implementation NSFileHandle (NSFileHandleSocketConnection)

+(id)fileHandleForConnectionToHost:(NSString*)hostname atPort:(unsigned short)port
{
struct hostent *hostinfo;
struct sockaddr_in remoteAddr;
int fd;
int i;

// Resolve the hostname
hostinfo = gethostbyname([hostname cString]);
if (hostinfo==NULL)
{
[NSException raise:@"NSFileHandleSocketConnection"
format:@"Could not find host"];
}

// Retrieve a socket
fd = socket(PF_INET,SOCK_STREAM,0);
if (fd==-1)
{
[NSException raise:@"NSFileHandleSocketConnection"
format:@"Could not open a socket"];
}

// Try to make a connection to the host by trying all possible addresses
bzero((char*)&remoteAddr, sizeof(remoteAddr));
remoteAddr.sin_family = AF_INET;
remoteAddr.sin_port = htons(port);
for(i=0;hostinfo->h_addr_list[i]!=NULL;i++)
{
remoteAddr.sin_addr = *(struct in_addr *)hostinfo->h_addr_list[i];
if(connect(fd,(struct sockaddr *)&remoteAddr,sizeof(remoteAddr))==0)
{
// Connection was succesfull
return [[NSFileHandle alloc] initWithFileDescriptor:fd closeOnDealloc:YES];
}
}

// No connection could be made
[NSException raise:@"NSFileHandleSocketConnection"
format:@"Could not connect to host"];

// Should never be reached
return nil;
}
@end
---

Rgrds,
Sander Niemeijer

On zondag, december 23, 2001, at 08:45 , Chris Parker wrote:

Hi Sander,

On Saturday, December 22, 2001, at 07:00 AM, email@hidden wrote:

* Bugger all and write my own classes using the BSD layer
I hope it won't have to come to that, but I could also write my own classes (much the way OMNI did) using POSIX and make it asynchronous by using an NSTimer.

* Any other???

You may wish to look at NSFileHandle. Although you'd have to create the network socket in the traditional manner, you can create an NSFileHandle from the file descriptor resulting from that by using initWithFileDescriptor:closeOnDealloc:

Once you've got that set up you can add another object as an observer of the NSFileHandleReadCompletionNotification which will tell you when you get data on the socket.

Once you've got that set up, you can use readInBackgroundAndNotify: in order to have it read in the background and issue the notification above.

.chris

--
Chris Parker
Cocoa Frameworks Engineer
Apple Computer, Inc.


References: 
 >Re: TCP/IP Connections (From: Chris Parker <email@hidden>)

  • Prev by Date: Windows in multiple NIBs
  • Next by Date: Re: TCP/IP Connections
  • Previous by thread: Re: TCP/IP Connections
  • Next by thread: Re: TCP/IP Connections
  • Index(es):
    • Date
    • Thread