動くけど、C言語の流儀は無視した作りになってしまった…。
parseURLではsubstringっぽい処理が多い。
C言語では区切りたい所に\0を突っ込んで終わりを示すのが普通らしい。
関数がポインタを返すのもよくないのかも知れない。
ソースは大体ここから。
C 言語で HTTP クライアントを作ってみよう (1)
http://x68000.q-e-d.net/~68user/net/c-http-1.html
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <netdb.h> #include <sys/socket.h> #include <netinet/in.h> #define BUF_LEN 256 typedef struct { char schema[10]; char domain[255]; char path[255]; int port; } URL; URL *parseURL(char *url) { URL *obj; char *p; char *p_domain; char *p_path; char *p_end; obj = (URL *)malloc(sizeof(URL)); memset(obj, '\0', sizeof(URL)); p_end = url + strlen(url); p = strstr(url, "://"); if (p) { strncpy(obj->schema, url, p-url); p_domain = url+strlen(obj->schema)+3; if (p_path = strchr(p_domain, '/')) { strncpy(obj->domain, p_domain, p_path-p_domain); strncpy(obj->path, p_path, p_end-p_path); } else { strncpy(obj->domain, p_domain, p_end-p_domain); strcpy(obj->path, "/"); } if (p = strchr(obj->domain, ':')) { obj->port = atoi(p+1); *p = '\0'; } if (0<strlen(obj->domain)) { return obj; } } return NULL; } int main(int argc, char *argv[]) { int s; struct hostent *servhost; struct in_addr addr; struct sockaddr_in server; char send_buf[BUF_LEN]; int i; URL *url; if (argc<2) { printf("usage: %s http://domain/path\n", argv[0]); return 1; } url = parseURL(argv[1]); if (url == NULL) { printf("Parse error: %s\n", argv[1]); return 1; } servhost = gethostbyname(url->domain); if (servhost == NULL) { printf("IP変換失敗\n"); return 1; } printf("servhost->h_name: %s\n", servhost->h_name); for (i=0; servhost->h_aliases[i]; i++) { printf("servhost->h_aliases[%u]: %s\n", i, servhost->h_aliases[i]); } printf("servhost->h_addrtype: %u\n", servhost->h_addrtype); printf("servhost->h_length: %u\n", servhost->h_length); for (i=0; servhost->h_addr_list[i]; i++) { memcpy(&addr, servhost->h_addr_list[i], 4); printf("servhost->h_addr_list[%u]: %s\n", i, inet_ntoa(addr)); } printf("\n"); memset(&server, '\0', sizeof(server)); server.sin_family = AF_INET; memcpy(&server.sin_addr, servhost->h_addr, servhost->h_length); server.sin_port = htons(80); // ソケット作成 if ( (s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("ソケット作成失敗\n"); return 1; } // 接続 if (connect(s, (struct sockaddr *)&server, sizeof(server)) == -1) { printf("接続失敗\n"); return 1; } // write sprintf(send_buf, "GET %s HTTP/1.1\r\n", url->path); write(s, send_buf, strlen(send_buf)); sprintf(send_buf, "host: %s\r\n", url->domain); write(s, send_buf, strlen(send_buf)); sprintf(send_buf, "\r\n"); write(s, send_buf, strlen(send_buf)); // read while (1) { char buf[BUF_LEN]; memset(buf, '\0', BUF_LEN); int read_size; read_size = read(s, buf, BUF_LEN); if (0<read_size) { write(1, buf, read_size); } else { break; } } close(s); free(url); return 0; }