Re: Getting started communicating with AFP -- on the right track?
Re: Getting started communicating with AFP -- on the right track?
- Subject: Re: Getting started communicating with AFP -- on the right track?
- From: Jerry Krinock <email@hidden>
- Date: Tue, 7 Jul 2009 20:56:57 -0700
Still trying to get info from an AppleShare server using Berkeley
sockets....
Jens' project [1] seems to use NSStream, and the afpfs-ng source code
[2] is a little too "modular" for me to easily see what happens at a
low level in one day. So, I threw together some code from a book I
have [3] and info I found on the net [4].
I believe I understand everything in the code. But I'm not sure about
the Apple Filing Protocol (AFP). One thing that bothers me is that,
in the AFP Reference, all the commands have a "result" code. Yet the
"reply block" is defined byte-for-byte. [5] I write my command to the
socket and read the response from the server. Where would this result
code appear?
My code succeeds in connecting to the server and writing the two-byte
command to the socket, but never gets a response. The read() function
returns after a 2-minute timeout...
[Session started at 2009-07-07 20:27:15 -0700.]
2009-07-07 20:27:15.783 MyTool[92332:10b] 1999: Got fd 3
2009-07-07 20:27:15.791 MyTool[92332:10b] 2707: Reading response from
server...
2009-07-07 20:29:19.817 MyTool[92332:10b] 2750: Received EOF
2009-07-07 20:29:19.818 MyTool[92332:10b] 2926: Done!
If anyone could see what's missing, I'd appreciate it. Apple's AFP
Programming Guide [6] explains exactly what I'm trying to do: "After a
user selects an AFP server to log in to, the AFP client sends the
FPGetSrvrInfo command to request information about that server. The
server returns information that includes...[all the stuff I want!]"
#import <Cocoa/Cocoa.h> // for NSLog()
#import <netinet/in.h> // for sockaddr_in
#import <sys/socket.h> // for socket(), AF_INET
#import <netdb.h> // for gethostbyname2, h_errno, etc
#import <errno.h> // for errno
#import <string.h> // for strerror
#import <stdlib.h> // for EXIT_SUCCESS
#import <unistd.h> // for close
#define APPLESHARE_PORT 548
// I can't seem to find a header file anywhere on my system which
defines
// the command codes for the AFP Protocol. Even in Apple Sample Code,
// there is a huge file of enums:
// http://developer.apple.com/samplecode/PGPuam/listing1.html
// I just define the one that I need:
#define kFPGetSrvrInfo 15
int main (int argc, const char * argv[]) {
char* dottedIPv4Address = "10.0.1.204" ;
int programResult = EXIT_FAILURE;
int fd = -1, result;
struct sockaddr_in serverAddress;
struct hostent *hostInfo;
hostInfo = gethostbyname2 (dottedIPv4Address, AF_INET);
if (hostInfo == NULL) {
NSLog(@"1041: gethostbyname2 failed for '%s'",
dottedIPv4Address) ;
NSLog(@"1064: error: %d / %s", h_errno, hstrerror(h_errno)) ;
goto bailout;
}
serverAddress.sin_len = sizeof (struct sockaddr_in);
serverAddress.sin_family = AF_INET ;
serverAddress.sin_port = htons(APPLESHARE_PORT) ;
serverAddress.sin_addr = *((struct in_addr *)(hostInfo->h_addr));
memset (&(serverAddress.sin_zero), 0,
sizeof(serverAddress.sin_zero));
result = socket (AF_INET, SOCK_STREAM, 0);
if (result == -1) {
NSLog(@"1801: Could not make a socket. error: %d / %s",
errno, strerror(errno));
goto bailout;
}
fd = result;
NSLog(@"1999: Got fd %d", fd) ;
// Client does not need to bind() or listen() with connect()
result = connect (fd, (struct sockaddr *)&serverAddress,
sizeof(serverAddress));
if (result == -1) {
NSLog(@"2075: Could not connect. error: %d / %s",
errno, strerror(errno));
goto bailout;
}
// The FPGetSrvrInfo command is defined as simply two bytes
// It is two bytes. Put our command into a buffer.
char buffer[4096] ;
buffer[0] = kFPGetSrvrInfo ; // Command Code
buffer[1] = 0 ; // Pad
size_t commandSize = 2 ;
// Send our command to the server
result = write (fd, buffer, commandSize) ;
if (result == -1) {
NSLog(@"2614: error writing: %d / %s", errno,
strerror(errno)) ;
}
// Drain the socket
while (1) {
NSLog(@"2707: Reading response from server...") ;
result = read (fd, buffer, 4095) ;
if (result == 0) {
NSLog(@"2750: Received EOF") ;
break ;
}
else if (result == -1) {
NSLog(@"2805: Could not read from remote socket."
"error %d / %s", errno, strerror(errno)) ;
break ;
}
else {
// Null terminate the buffer so we can print it.
buffer[result] = '\000' ;
// Print the buffer
NSLog(@"2850: Received data: %s", buffer) ;
}
}
close (fd) ;
/*DB?Line*/ NSLog(@"2926: Done!") ;
programResult = EXIT_SUCCESS;
bailout:
close (fd);
return (programResult);
}
1. http://bitbucket.org/snej/mynetwork/wiki/Home
2. http://sourceforge.net/projects/afpfs-ng/
3. Advanced Mac OS X Programming, 2nd ed by Dalrymple & Hillegass,
Chapter 11
4. http://cs.nyu.edu/~yap/classes/visual/01f/lect/l7/l_14.html
5. http://developer.apple.com/documentation/Networking/Reference/AFP_Reference/Reference/reference.html#/
/apple_ref/doc/uid/TP40003548-CH3-CHDIEGED
6. http://developer.apple.com/documentation/networking/conceptual/afp/Concepts/Concepts.html#/
/apple_ref/doc/uid/TP40000854-CH3-CHBGCJDA
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden