📄 test5.c
字号:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <string.h>#include <errno.h>#include <arpa/inet.h>#include <netdb.h>#define REMOTE_HOST "192.168.0.1"#define REMOTE_PORT 80int main(int argc, char **argv){ int fd; char *remote_host; unsigned short remote_port; unsigned long resolved_remote_host; if (argc < 3) { fprintf(stderr, "Usage: %s <target host> <target port>\n", argv[0]); exit(1); } remote_host = argv[1]; remote_port = atoi(argv[2]); //int socket(int domain, int type, int protocol);/* Name Purpose Man page PF_UNIX, PF_LOCAL Local communication unix(7) PF_INET IPv4 Internet protocols ip(7) PF_INET6 IPv6 Internet protocols PF_IPX IPX - Novell protocols PF_NETLINK Kernel user interface device netlink(7) PF_X25 ITU - T X .25 / ISO - 8208 protocol x25(7) PF_AX25 Amateur radio AX .25 protocol PF_ATMPVC Access to raw ATM PVCs PF_APPLETALK Appletalk ddp(7) PF_PACKET Low level packet interface packet(7)*/ /* SOCK_STREAM Provides sequenced, reliable, two - way, connection - based byte streams.An out - of - band data trans - mission mechanism may be supported. SOCK_DGRAM Supports datagrams(connectionless, unreliable messages of a fixed maximum length).SOCK_SEQPACKET Provides a sequenced, reliable, two - way connection - based data transmission path for datagrams of fixed maximum length; a consumer is required to read an entire packet with each read system call. SOCK_RAW Provides raw network protocol access.SOCK_RDM Provides a reliable datagram layer that does not guarantee ordering.SOCK_PACKET Obsolete and should not be used in new programs; see packet(7). */ // XXX: step 1, socket() //if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { fprintf(stdout, "Create socket by socket() failed: %s\n", strerror(errno)); return 0; } fprintf(stdout, "New created socket = %d\n", fd); // TODO: step 1.4, DNS resolve //struct hostent *gethostbyaddr(const void *addr, socklen_t len, //struct hostent *gethostbyname(const char *name); struct hostent *h = NULL; h = gethostbyname(remote_host); if (h == NULL) { fprintf(stderr, "gethostbyname() failed, h_errno = %d\n", h_errno); //The variable h_errno can have the following values: switch (h_errno) { case HOST_NOT_FOUND: fprintf(stderr, "The specified host is unknown.\n"); break; case NO_ADDRESS: //case NO_DATA: fprintf(stderr, "The requested name is valid but does not have an IP address.\n"); break; case NO_RECOVERY: fprintf(stderr, "A non-recoverable name server error occurred.\n"); break; case TRY_AGAIN: fprintf(stderr, "A temporary error occurred on an authoritative name server. Try again later.\n"); break; } // FIXME: check error code, and deal with it exit(1); } fprintf(stdout, "DNS resolv successed.\n");#if 0 struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* host address type */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses */ }# define h_addr h_addr_list[0] /* for backward compatibility */#endif fprintf(stdout, "official name of host: %s\n", h->h_name); //fprintf(stdout, "alias list: %s", h->h_name); char **pp; pp = h->h_aliases; while (pp && *pp) { fprintf(stdout, "\t%s\n", *pp); pp++; } fprintf(stdout, "host address type: %d\n", h->h_addrtype); fprintf(stdout, "length of address: %d\n", h->h_length); fprintf(stdout, "list of addresses:\n"); int i = 0; pp = h->h_addr_list; while (pp && *pp) { //p = inet_ntoa(*((struct in_addr *) &addr1)); fprintf(stdout, "\t%p -> %s\n", *pp, inet_ntoa(*(struct in_addr *) *pp)); //fprintf(stdout, "\t%s\n", inet_ntoa(*(struct in_addr *)*pp)); pp++; if (i == 0) { resolved_remote_host = *(unsigned long *)*pp; i++; } } // XXX: step 1.5 prepare remote server data struct // int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen); struct sockaddr_in remote_addr; memset(&remote_addr, 0, sizeof(remote_addr)); remote_addr.sin_family = PF_INET; remote_addr.sin_port = htons(remote_port); //remote_addr.sin_addr.s_addr = inet_addr(remote_host); remote_addr.sin_addr.s_addr = resolved_remote_host; // XXX: step 2, connect to remote server if (connect(fd, (struct sockaddr *) &remote_addr, sizeof(remote_addr)) < 0) { fprintf(stdout, "connect to remote host: %s:%d failed: %s\n", remote_host, remote_port, strerror(errno)); return 0; } fprintf(stdout, "Connected to remote host: %s:%d\n", remote_host, remote_port); // XXX: step 3, send request //ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset); //ssize_t write(int fildes, const void *buf, size_t nbyte); char buf[1024]; memset(buf, 0, sizeof(buf)); strcpy(buf, "GET / HTTP/1.1\n\n"); // FIXME: check return value fo write() if (write(fd, buf, sizeof(buf)) < 0) { fprintf(stdout, "Send request to %s:%d failed: %s\n", remote_host, remote_port, strerror(errno)); return 0; } // XXX: step 4, read response from remote server //ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset); //ssize_t read(int fildes, void *buf, size_t nbyte); ssize_t n; while ((n = read(fd, buf, sizeof(buf))) > 0) { fprintf(stdout, "%s", buf); } if (n < 0) { fprintf(stdout, "Read from %s:%d encounter a error: %s\n", remote_host, remote_port, strerror(errno)); return 0; } else if (n == 0) { fprintf(stdout, "Remote disconnected.\n"); close(fd); } // XXX: step 5, disconnect from remote server close(fd); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -