[ Pobierz całość w formacie PDF ]
the official host name, a list of aliases, the address type, the length of the addresses, and the list of addresses it's a general-purpose structure that's pretty easy to use for our specific purposes once you see how.) gethostbyaddr() takes a struct in_addr and brings you up a corresponding host name (if there is one), so it's sort of the reverse of gethostbyname(). As for parameters, even though addr is a char*, you actually want to pass in a pointer to a struct in_addr. len should be sizeof(struct in_addr), and type should be AF_INET. So what is this struct hostent that gets returned? It has a number of fields that contain information about the host in question. char *h_name The real canonical host name. char **h_aliases A list of aliases that can be accessed with arrays the last element is NULL int h_addrtype The result's address type, which really should be AF_INET for our purposes.. int length The length of the addresses in bytes, which is 4 for IP (version 4) addresses. char **h_addr_list A list of IP addresses for this host. Although this is a char**, it's really an array of struct in_addr*s in disguise. The last array element is NULL. h_addr A commonly defined alias for h_addr_list[0]. If you just want any old IP address for this host (yeah, they can have more than one) just use this field. Return Value Returns a pointer to a resultant struct hostent or success, or NULL on error. Instead of the normal perror() and all that stuff you'd normally use for error reporting, these functions have parallel results in the variable h_errno, which can be printed using the functions herror() or hstrerror(). These work just like the classic errno, perror(), and strerror() functions you're used to. Beej's Guide to Network Programming 59 Example int i; struct hostent *he; struct in_addr **addr_list; struct in_addr addr; // get the addresses of www.yahoo.com: he = gethostbyname("www.yahoo.com"); if (he == NULL) { // do some error checking herror("gethostbyname"); // herror(), NOT perror() exit(1); } // print information about this host: printf("Official name is: %s\n", he->h_name); printf("IP address: %s\n", inet_ntoa(*(struct in_addr*)he->h_addr)); printf("All addresses: "); addr_list = (struct in_addr **)he->h_addr_list; for(i = 0; addr_list[i] != NULL; i++) { printf("%s ", inet_ntoa(*addr_list[i])); } printf("\n"); // get the host name of 66.94.230.32: inet_aton("66.94.230.32", &addr); he = gethostbyaddr(&addr, sizeof addr, AF_INET); printf("Host name: %s\n", he->h_name); See Also gethostname(), errno, perror(), strerror(), struct in_addr Beej's Guide to Network Programming 60 8.7. getpeername() Return address info about the remote side of the connection Prototypes #include int getpeername(int s, struct sockaddr *addr, socklen_t *len); Description Once you have either accept()ed a remote connection, or connect()ed to a server, you now have what is known as a peer. Your peer is simply the computer you're connected to, identified by an IP address and a port. So... getpeername() simply returns a struct sockaddr_in filled with information about the machine you're connected to. Why is it called a name ? Well, there are a lot of different kinds of sockets, not just Internet Sockets like we're using in this guide, and so name was a nice generic term that covered all cases. In our case, though, the peer's name is it's IP address and port. Although the function returns the size of the resultant address in len, you must preload len with the size of addr. Return Value Returns zero on success, or -1 on error (and errno will be set accordingly.) Example int s; struct sockaddr_in server, addr; socklen_t len; // make a socket s = socket(PF_INET, SOCK_STREAM, 0); // connect to a server server.sin_family = AF_INET; inet_aton("63.161.169.137", &server.sin_addr); server.sin_port = htons(80); connect(s, (struct sockaddr*)&server, sizeof server); // get the peer name // we know we just connected to 63.161.169.137:80, so this should print: // Peer IP address: 63.161.169.137 // Peer port : 80 len = sizeof addr; getpeername(s, (struct sockaddr*)&addr, &len); printf("Peer IP address: %s\n", inet_ntoa(addr.sin_addr)); printf("Peer port : %d\n", ntohs(addr.sin_port)); See Also gethostname(), gethostbyname(), gethostbyaddr() Beej's Guide to Network Programming 61 8.8. errno Holds the error code for the last system call Prototypes #include int errno; Description This is the variable that holds error information for a lot of system calls. If you'll recall, things like socket() and listen() return -1 on error, and they set the exact value of errno to let you know specifically which error occurred. The header file errno.h lists a bunch of constant symbolic names for errors, such as EADDRINUSE, EPIPE, ECONNREFUSED, etc. Your local man pages will tell you what codes can be returned as an error, and you can use these at run time to handle different errors in different ways. Or, more commonly, you can call perror() or strerror() to get a human-readable version of the error. Return Value The value of the variable is the latest error to have transpired, which might be the code for success if the last action succeeded. Example s = socket(PF_INET, SOCK_STREAM, 0); if (s == -1) { perror("socket"); // or use strerror() } tryagain: if (select(n, &readfds, NULL, NULL) == -1) { // an error has occurred!! // if we were only interrupted, just restart the select() call: if (errno == EINTR) goto tryagain; // AAAA! goto!!! // otherwise it's a more serious error: perror("select"); exit(1); } See Also perror(), strerror() Beej's Guide to Network Programming 62 8.9. fcntl() Control socket descriptors Prototypes #include #include int fcntl(int s, int cmd, long arg); Description This function is typically used to do file locking and other file-oriented stuff, but it also has a couple socket-related functions that you might see or use from time to time. Parameter s is the socket descriptor you wish to operate on, cmd should be set to F_SETFL, and arg can be one of the following commands. (Like I said, there's more to fcntl() than I'm letting on here, but I'm trying to stay socket-oriented.) O_NONBLOCK Set the socket to be non-blocking. See the section on blocking for more details. O_ASYNC Set the socket to do asynchronous I/O. When data is ready to be recv()'d on the socket, the signal SIGIO will be raised. This is rare to see, and beyond the scope of the guide. And I think it's only available on certain systems. Return Value Returns zero on success, or -1 on error (and errno will be set accordingly.) Different uses of the fcntl() actually have different return values, but I haven't covered them here because they're not socket-related. See your local fcntl() man page for more information. Example int s = socket(PF_INET, SOCK_STREAM, 0); fcntl(s, F_SETFL, O_NONBLOCK); // set to non-blocking fcntl(s, F_SETFL, O_ASYNC); // set to asynchronous I/O See Also Blocking, send() Beej's Guide to Network Programming 63 8.10. htons(), htonl(), ntohs(), ntohl() Convert multi-byte integer types from host byte order to network byte order Prototypes #include uint32_t htonl(uint32_t hostlong); [ Pobierz całość w formacie PDF ] |