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 +网址即可