LINUX C语言网络编程
2017-02-10 本文已影响81人
erU
SOC实现一个HTTP请求
总纲
- 创建SOC
- 连接SOC
- 发送HTTP请求头数据
- 接收返回的数据
创建SOC
socket
域名解析
连接网络的时候需要传入目的服务器的 ip地址字节流(e5acc965)
- 进行域名(www.csdn.net)解析
gethostbyname
- 转换获取到ip地址字符串(101.201.172.229)
inet_ntop
- 对ip地址字符串转换得到 ip地址字节流(e5acc965)
inet_pton
连接SOC
connect
设置端口和网络类型
发送HTTP请求头数据
write
- 请求头是由固定格式组成。
1.1. 请求行
1.2. 请求体
char buf[] = "GET /index.html HTTP/1.1\r\n\
Host: 101.201.172.229:8080\r\n\
Proxy-Connection: keep-alive\r\n\
Cache-Control: max-age=0\r\n\
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n\
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36\r\n\
Accept-Encoding: gzip,deflate,sdch\r\n\
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6\r\n\
\r\n";
接收服务器返回的数据
read
源码
////
//// main.c
//// c_http
////
//// Created by king eru on 2017/2/9.
//// Copyright © 2017年 nd_oneWater. All rights reserved.
////
//
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netdb.h>
int main()
{
int sock,n;
struct hostent *hent;
struct sockaddr_in servaddr = { 0 };
char host_name[] = "www.csdn.net";
char ip[32] = { 0 };
char buf[] = "GET /index.html HTTP/1.1\r\n\
Host: 101.201.172.229:8080\r\n\
Proxy-Connection: keep-alive\r\n\
Cache-Control: max-age=0\r\n\
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n\
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36\r\n\
Accept-Encoding: gzip,deflate,sdch\r\n\
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6\r\n\
\r\n";
char rbuf[2048] = { 0 };
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
perror("tcp creat error");
exit(1);
}
if((hent=gethostbyname(host_name))==NULL){
perror("ip error");
exit(2);
}
{
int32_t ipi = 0;
ipi = (*(*hent->h_addr_list + 3) << 24) & 0xFF000000;
ipi |= ((*(*hent->h_addr_list + 2) << 16) & 0xFF0000);
ipi |= ((*(*hent->h_addr_list + 1) << 8) & 0xFF00);
ipi |= ((*(*hent->h_addr_list + 0) << 0) & 0xFF);
printf(" 0x%x \n",ipi);//这也是正确的ip地址流 对位操作的时候需要知道 大小端 熟悉指针操作
}
//获取到网络类型 ipv4 ipv6 两个类型 网络地址族
printf("%d\n",hent->h_addrtype);
//解析出 点分 地址
//网络字节流 ——》IP字符串 0.0.0.0
if (inet_ntop(hent->h_addrtype,(void *)hent->h_addr_list[0],ip,sizeof(ip)) == NULL) {
perror("inet_ntop error");
exit(4);
}
printf("ip %s\n",ip);
//IP字符串 ——》网络字节流
if(inet_pton(hent->h_addrtype,ip,&servaddr.sin_addr) <= 0){
perror("inet_pton error");
exit(5);
}
printf("ips 0x%x\n",servaddr.sin_addr);
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(80);
if (connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
perror("connect error\n");
exit(6);
}
write(sock, buf, strlen(buf));
while ((n = read(sock, rbuf, 2048))>0) {
rbuf[n] = 0;
printf("%s", rbuf);
}
printf("ok\n");
close(sock);
return 0;
}