#pragma mark Includes
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#pragma mark -
#pragma mark Global Definitions
CFReadStreamRef gReadStream = NULL;
CFWriteStreamRef gWriteStream = NULL;
#pragma mark -
#pragma mark Static Function Declarations
///--2009-9-27-zorro
static Boolean Connect(const char* host, UInt16 port, UInt32 timeOut);
static void Disconnect();
static Boolean IsConnect();
static long SendData(const char * buffer,long length);
static long ReceiveData(char * buffer,long length);
#pragma mark -
#pragma mark Static Function Definitions
/* static */ Boolean
WaitForConnection(CFWriteStreamRef wStream, UInt32 timeOut) {
// Since in this test app we have nothing better to do, we just poll to check whether
// the connection has succeeded. In a GUI app, the better approach would be to return
// to the RunLoop to service events, and watch for the kCFStreamEventCanAcceptBytes event.
int i;
for (i = 0; i < timeOut; i++) {
if (CFWriteStreamCanAcceptBytes(wStream))
return TRUE;
if (i == 1)
fprintf(stdout, "Waiting for connection.../n");
sleep(1);
}
return FALSE;
}
/* static */ Boolean
Connect(const char* host, UInt16 port,UInt32 timeOut) {
// Check for a dotted-quad address, if so skip any host lookups
in_addr_t addr = inet_addr(host);
if (addr != INADDR_NONE) {
// Create the streams from numberical host
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_len= sizeof(sin);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = addr;
sin.sin_port = htons(port);
CFDataRef addressData = CFDataCreate(NULL, (UInt8 *)&sin, sizeof(sin));
CFSocketSignature sig = { PF_INET, SOCK_STREAM, IPPROTO_TCP, addressData };
// Create the streams.
CFStreamCreatePairWithPeerSocketSignature(kCFAllocatorDefault, &sig, &gReadStream, &gWriteStream);
CFRelease(addressData);
// Inform the streams to kill the socket when it is done with it.
// This effects the write stream too since the pair shares the
// one socket.
CFReadStreamSetProperty(gReadStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
///--2009-9-27-zorro
// Try to open the streams.
if (!CFReadStreamOpen(gReadStream))
{
return NO;
}
if(!CFWriteStreamOpen(gWriteStream))
{
CFReadStreamClose(gReadStream);
CFRelease(gReadStream);
gReadStream = NULL;
return NO;
}
if(WaitForConnection(gWriteStream,timeOut))
{
return YES;
}
else
{
CFReadStreamClose(gReadStream);
CFWriteStreamClose(gWriteStream);
CFRelease(gWriteStream);
CFRelease(gReadStream);
gWriteStream = NULL;
gReadStream = NULL;
}
}
return FALSE;
}
void Disconnect()
{
if (gReadStream)
{
CFReadStreamClose(gReadStream);
CFRelease(gReadStream);
gReadStream=NULL;
}
if (gWriteStream)
{
CFWriteStreamClose(gWriteStream);
CFRelease(gWriteStream);
gWriteStream=NULL;
}
}
Boolean IsConnect()
{
if(gWriteStream==NULL || gReadStream==NULL)
return FALSE;
CFStreamStatus rStatus = CFReadStreamGetStatus(gReadStream);
CFStreamStatus wStatus = CFWriteStreamGetStatus(gWriteStream);
if (rStatus == kCFStreamStatusError || wStatus == kCFStreamStatusError ||
rStatus == kCFStreamStatusClosed || wStatus == kCFStreamStatusClosed ||
rStatus == kCFStreamStatusAtEnd || wStatus == kCFStreamStatusAtEnd ||
rStatus == kCFStreamStatusNotOpen || wStatus == kCFStreamStatusNotOpen)
{
return FALSE;
}
return TRUE;
}
long SendData(const char * buffer,long length)
{
if(gWriteStream==NULL || buffer==NULL || length==0)
return 0;
// Try to send
CFIndex bytesSent = CFWriteStreamWrite(gWriteStream, (const UInt8 *)buffer, length);
return bytesSent;
}
long ReceiveData(char * buffer,long length)
{
if(gReadStream==NULL || buffer==NULL || length==0)
return 0;
// Try to receive
CFIndex bytesRead = CFReadStreamRead(gReadStream, (UInt8 *)buffer,length);
if (bytesRead > 0)
{
// Terminate the received string
buffer[bytesRead] = '/0';
// Print it out for the user
//fprintf(stdout, "Received: %s/n", buffer);
}
return bytesRead;
}
#pragma mark -