LINUX C语言网络编程

2017-02-10  本文已影响81人  erU

SOC实现一个HTTP请求

总纲

  1. 创建SOC
  1. 连接SOC
  2. 发送HTTP请求头数据
  3. 接收返回的数据

创建SOC

socket

域名解析

连接网络的时候需要传入目的服务器的 ip地址字节流(e5acc965)

  1. 进行域名(www.csdn.net)解析 gethostbyname
  2. 转换获取到ip地址字符串(101.201.172.229) inet_ntop
  3. 对ip地址字符串转换得到 ip地址字节流(e5acc965) inet_pton

连接SOC

connect
设置端口和网络类型

发送HTTP请求头数据

write

  1. 请求头是由固定格式组成。
    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;
}


上一篇下一篇

猜你喜欢

热点阅读