HTTP请求

        在浏览器与服务器建立连接发送请求时,首先在socket基础上建立TCP连接,发送http请求,服务器在停车票连接上,返回http协议response。

1.域名翻译为IP地址

        除了使用DNS请求域名外,还可以使用gethostbyname(); 

struct hostent* host_entry = gethostbyname(hostname);

返回一个实例,包括主机名,字段长度,IP列表。

struct hostent{
    char *h_name;     //地址正式名称
    char *h_aliases;  //地址预备名称指针
    short h_addrtype; //地址类型
    short h_length;   //地址比特长度
    char **h_addr_list; // 主机网络地址指针
};

将点分十进制转化为字符串指针 

//255.255.255.255 点分十进制
inet_ntoa(*(struct in_addr*)*host_entry->h_addr_list);

2.tcp socket连接

        建立socket句柄  sockfd 为file descriptor 看做一个文件,在socket上收发,相当于对一个文件进行读写。 

        SOCK_STREAM 为TCP连接

        SOCK_DGRAM为UDP连接

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

        建立地址结构并连接,设置为非阻塞模式

struct sockaddr_in sin={0};
sin.sin_family=AF_INET;
sin.sin_port=htons(80);
sin.sin_addr.s_addr = inet_addr(ip);
connect(sockfd,(struct sockaddr*)&sin,sizeof(struct sockaddr_in))); //连接服务器
fcntl(sockfd,F_SETFL,O_NONBLOCK);

         struct sockaddr_in结构如下

struct sockaddr_in{
       sin_family  //地址族协议
       sin_port
       struct in_addr sin_addr;//地址
}
struct in_addr{
       in_addr_t s_addr;
}

       阻塞接收时,会一直等待到数据到来,非阻塞接收时,无数据则返回

 inet_addr();//将有效字符串转化为32位二进制网络字节序的IPV4地址

 fcntl(FD,CMD.LOCK);//函数用于改变fd指定文件的特征

//cmd 为F_SETFL时,lock位可以为O_APPENO,O_NONBLOCK,O_ASYNC

3.发送请求

        按照HTTP协议,将【请求资源、版本号】,【域名】,【连接方式】整合到一个char【】中,进行请求发送。

char * http_send_request(const char *hostname, const char *resource) {

	char *ip = host_to_ip(hostname); // 
	int sockfd = http_create_socket(ip);

	char buffer[BUFFER_SIZE] = {0};
	sprintf(buffer, 
"GET %s %s\r\n\
Host: %s\r\n\
%s\r\n\
\r\n",

	resource, HTTP_VERSION,
	hostname,
	CONNETION_TYPE
	);

	send(sockfd, buffer, strlen(buffer), 0);

	fd_set fdread; //io组是否有数据可读的标志组
	
	FD_ZERO(&fdread);
	FD_SET(sockfd, &fdread); // jiang fd 加入到集合中  一起判断

	struct timeval tv;
	tv.tv_sec = 5;
	tv.tv_usec = 0;

	char *result = malloc(sizeof(int));
	memset(result, 0, sizeof(int));
	
	while (1) {

		int selection = select(sockfd+1, &fdread, NULL, NULL, &tv);
        //select(IO数量+1,可读集合,可写,出错,轮询时间);
		if (!selection || !FD_ISSET(sockfd, &fdread)) { 
          //FD_ISSET 判断fd是否在fd_set中,避免数据出错 检测到返回真
			break;
		} else {

			memset(buffer, 0, BUFFER_SIZE);
			int len = recv(sockfd, buffer, BUFFER_SIZE, 0);
			if (len == 0) {   //为对方关闭
				break;
			}

			result = realloc(result, (strlen(result) + len + 1) * sizeof(char));
			strncat(result, buffer, len);
		}

	}

	return result;
}
struct timeval{

   time_t tv_sec; //sec
   suseconds_t tv_usec;//毫sec

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值