c语言实现HTTP客户端

HTTP协议,简单来说就是一种通话的格式,比如,第一个字节是方法,告诉服务器,我要执行哪种操作,接下来是版本之类的,但是HTTP最根本来时还是通过网络发送一段数据,只不过这段数据需要符合HTTP的协议规则

MY_HTTP.h

#ifndef __MY_HTTP_H

#define __MY_HTTP_H

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <sys/socket.h>

#include <netdb.h>

#include <arpa/inet.h>

#include <errno.h>

#include <sys/time.h>

#include <sys/types.h>

#include <unistd.h>

#define HTTP_PR(mesg, args...) fprintf(stdout, "[HTTP print:%s:%d:] "mesg" ", __FILE__, __LINE__, ##args)  

typedef enum 

{

    HTTP_ERR,

    HTTP_OK

}HTTP_Statues;

HTTP_Statues socket_init(int *sockfd,char *fhostname);

#endif

MY_HTTP.c

#include "My_http.h"

int main(int argc,char **argv)

{

    char message[512];

    if(argc != 2)

    {

        HTTP_PR("parameter error\n");

        exit(-1);

    }

    int socket_desc;

    char *hostname = argv[1];

    if(socket_init(&socket_desc,hostname)!= HTTP_OK)

    {

        HTTP_PR("socket_init error\n");

        exit(-1);

    }

    else 

    {

        HTTP_PR("socket_init success!!\n");

    }

    // message = "GET / HTTP/1.1\r\nHost: www.baidu.com\r\n\r\n"; //构建要发送的消息

    sprintf(message,"GET / HTTP/1.1\r\nHost: %s\r\n\r\n",argv[1]);

    if(send(socket_desc,message,strlen(message),0) < 0)

    {

        HTTP_PR("send error");

        exit(-1);

    }

    struct timeval timeout = {3, 0};

    setsockopt(socket_desc, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));

    //Receive a reply from the server

    //loop

    int size_recv, total_size = 0;

    char chunk[512];

    fd_set fdset;

    FD_ZERO(&fdset);

    FD_SET(socket_desc,&fdset);

    while(1) {

        select(socket_desc+1,&fdset,NULL,NULL,NULL);

        if(FD_ISSET(socket_desc,&fdset))

        {

            memset(chunk , 0 , 512); //clear the variable

            //获取数据

            if ((size_recv =  recv(socket_desc, chunk, 512, 0) ) == -1) 

            {

                if (errno == EWOULDBLOCK || errno == EAGAIN) {

                    HTTP_PR("recv timeout ...\n");

                    break;

                } else if (errno == EINTR) {

                    HTTP_PR("interrupt by signal...\n");

                    continue;

                } else if (errno == ENOENT) {

                    HTTP_PR("recv RST segement...\n");

                    break;

                } else {

                    HTTP_PR("unknown error: %d\n", errno);

                    exit(1);

                }

                HTTP_PR("error\n");

            } 

            else if (size_recv == 0) 

            {

                HTTP_PR("peer closed ...\n");

                break;

            } 

            else 

            {

                total_size += size_recv;

                HTTP_PR("%s" , chunk);

            }

        }

       

    }

    HTTP_PR("Reply received, total_size = %d bytes\n", total_size);

    return 0;

}

HTTP_Statues socket_init(int *sockfd,char *fhostname)

{

     struct sockaddr_in server;

    char ip[20] = {0};

    *sockfd  = socket(AF_INET,SOCK_STREAM,0);

    if(-1 == (*sockfd))

    {

        HTTP_PR("socket error\n");

        exit(-1);

    }

    struct hostent *hp;

    if(NULL == (hp = gethostbyname(fhostname)))

    {

        HTTP_PR("gethostbyname\n");

        exit(-1);

    }

    strcpy(ip, inet_ntoa(*(struct in_addr *)hp->h_addr_list[0]));

    server.sin_addr.s_addr = inet_addr(ip);

    server.sin_family = AF_INET;

    server.sin_port = htons(80);

    if(connect((*sockfd),(struct sockaddr *)&server,sizeof(server)) < 0)

    {

       HTTP_PR("connect\n");

       exit(-1);

    }

    else

    {

        HTTP_PR("connect success\n");

    }

    return HTTP_OK;

 

}

只需要gcc MY_HTTP.c -o HTTP之后./HTTP +网址即可

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值