Re: TCP/IP Connections
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.