• 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
RunLoop/CFSocket sample code for RAEL apps (LONG, pt2)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RunLoop/CFSocket sample code for RAEL apps (LONG, pt2)


  • Subject: RunLoop/CFSocket sample code for RAEL apps (LONG, pt2)
  • From: Jeffrey Johnson <email@hidden>
  • Date: Fri, 8 Feb 2002 13:14:49 -0500

// Continued from pt 1

// Apparently, we need to do a two-step dance to use a CFSocket:
// - Setup the socket first as a "rendevous" socket with a kCFSocketAcceptCallBack callback
// - When the accept callback fires, create a new CFSocket with the original "native" (BSD)
// socket with a kCFSocketDataCallBack callback to actually receive the data.
// - When the data callback fires, the data sent across the socket will be in dataPtr
// (a CFDataRef).
//
// In this example, each connection is a "one-shot" -i.e. the client connects, sends some
// data, optionally gets data back, then closes the socket. Because of this, the server
// does a CFInvalidate and CFRelease of the (data) CFSocket created in the accept callback. Another
// connection attempt by a client to this port number will tickle the accept callback,
// creating another data CFSocket, ad infinitum.
//


static void FESocketAcceptCallBack (CFSocketRef sock,
CFSocketCallBackType type,
CFDataRef theAddr,
const void * dataPtr,
void * info)
{
#pragma unused (sock, theAddr, type, info)

CFSocketRef newSock;
CFRunLoopSourceRef sourceRef;

if ((newSock = CFSocketCreateWithNative(kCFAllocatorDefault,
*(CFSocketNativeHandle *) dataPtr,
kCFSocketDataCallBack,
FESocketDataCallBack,
NULL)) != 0) {

sourceRef = CFSocketCreateRunLoopSource(kCFAllocatorDefault,
newSock,
0);
// same Carbon warning applies as above

CFRunLoopAddSource((CFRunLoopRef)GetCFRunLoopFromEventLoop(GetMainEventLoop()),
sourceRef,
kCFRunLoopDefaultMode);
CFRelease(sourceRef);
}
}

static void FESocketDataCallBack (CFSocketRef sock,
CFSocketCallBackType type,
CFDataRef theAddr,
const void * dataPtr,
void * info)
{
#pragma unused (theAddr, type, info)

CFIndex dataSize;

if ((dataSize = CFDataGetLength((CFDataRef)dataPtr)) > 0) {

// handle your data here. This example prints to stderr.
char *someBuf;
char stringOut[] = "%SUCCESS\n";
CFDataRef dataOut;

if ((someBuf = malloc(dataSize+1)) != nil) {

BlockMoveData(CFDataGetBytePtr((CFDataRef)dataPtr),someBuf,dataSize);
someBuf[dataSize] = '\0';
fprintf(stderr,"SocketUtils: socket received:\n|%s|\n",someBuf);
free(someBuf);
}
// we'll also send a response
if ((dataOut = CFDataCreate(kCFAllocatorDefault,
(const UInt8 *) stringOut,
strlen(stringOut))) != nil) {
CFSocketSendData(sock,NULL,dataOut,0);
CFRelease(dataOut);
};
}
CFSocketInvalidate(sock);
CFRelease(sock);
}

/***************
* sockClient.c *
***************/
// Test client program.
// Shamelessly adapted Jeffrey Johnson 02/08/02 to be self contained
// from a W. Richard Stevens Unix Network Programming example.

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>

#define MAXLINE 16384 /* max #bytes to request from server */

static ssize_t readn(int fd, void *vptr, size_t n);

int
main(int argc, char **argv)
{
int fd;
ssize_t n;
char request[MAXLINE], reply[MAXLINE];
struct sockaddr_in servaddr;

if (argc != 2) {
printf("usage: sockClient <port> ");
exit(1);
}

if ((fd = socket(AF_INET,SOCK_STREAM,0)) < 0) {
printf("socket error");
exit(2);
}

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(5555);
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

if (connect(fd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
printf("connect error");

// type some stuff, followed by a <CR>
if ( (n = read(STDIN_FILENO, request, MAXLINE)) == 0)
return(1); // connection closed by other end

write(fd, request, n);

n = readn(fd, reply, MAXLINE);
reply[n] = '\0';

printf("client received:\n%s\n", reply);

close(fd); /* TIME_WAIT on client, not server */

return(0);
}


static ssize_t /* Read "n" bytes from a descriptor. */
readn(int fd, void *vptr, size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;

ptr = vptr;
nleft = n;
while (nleft > 0) {
if ( (nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)
nread = 0; /* and call read() again */
else
return(-1);
} else if (nread == 0)
break; /* EOF */

nleft -= nread;
ptr += nread;
}
return(n - nleft); /* return >= 0 */
}
/* end readn */

--
Thanks
Jeffrey Johnson
Macintosh Development
Wavefunction, Inc.
_______________________________________________
macnetworkprog mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/macnetworkprog
Do not post admin requests to the list. They will be ignored.

  • Prev by Date: RunLoop/CFSocket sample code for RAEL apps (LONG, pt1)
  • Next by Date: Re: Name resolution limits
  • Previous by thread: Re: RunLoop/CFSocket sample code for RAEL apps
  • Next by thread: URL Access problem
  • Index(es):
    • Date
    • Thread