Menu Home

linux c 使用socket处理HTTP请求

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>

#define BUFSIZE 4096 

int main(int argc, char **argv) {

	int sockfd;
	struct sockaddr_in servaddr;
	charhttpRequest[BUFSIZE], buf[BUFSIZE];

	bzero(httpRequest, sizeof(httpRequest));
	
	//构建请求信息,这里请求http://192.168.2.184:8090/test.flv,这是一个由ffserver搭建的流媒体服务
	strcat(httpRequest, "GET /test.flv HTTP/1.1\n");
	strcat(httpRequest, "Host: 192.168.2.184:8090\n");
	strcat(httpRequest, "User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:23.0) Gecko/20100101 Firefox/23.0\n");
	strcat(httpRequest, "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n");
	strcat(httpRequest, "Accept-Language: en-US,en;q=0.5\n");
	strcat(httpRequest, "Accept-Encoding: gzip, deflate\n");
	//注意这里必须是2个"\n"
	strcat(httpRequest, "Connection: keep-alive\n\n");

        //http请求只支持tcp协议
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0) {
		fprintf(stderr, "create socket error\n");
		exit(1);
	}

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(PORT);
	if(inet_pton(AF_INET, IPSTR, &servaddr.sin_addr) <= 0) {
		fprintf(stderr, "inet_pton error\n");
                close(sockfd);
		exit(1);
	}
	
	if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
		fprintf(stderr, "connect error\n");
                close(sockfd);
		exit(1);
	}

	fprintf(stderr, "connect OK\n");
	fprintf(stderr, "httpRequest: %s\n",httpRequest);

        //发送请求
	int ret = write(sockfd,httpRequest, strlen(httpRequest));	
	if(ret < 0) {
		fprintf(stderr, "write error\n");
                close(sockfd);
		exit(1);
	}

	fprintf(stderr, "writen: %d\n", ret);

        //设置select的超时时间3S
        struct timeval tv;

	fd_set fdSet;

	//TODO: 接收数据,需要处理接收完成等
	while(true) {
                //因为select返回后tv的值是未定义的,所以每次需要重设一下
		tv.tv_sec = 3;
                tv.tv_usec = 0;

	        FD_ZERO(&fdSet);
	        FD_SET(sockfd, &fdSet);
		//这里的第5个参数指定超时时间
		int status = select(sockfd + 1, &fdSet, NULL, NULL, &tv);
                if(status > 0 && FD_ISSET(sockfd, &fdSet)) {
        
           	        memset(buf, 0, 4096);
			int i = read(sockfd, buf, 4096);

			//TODO:需要判断服务器是否返回了正确的状态等
			#if 1
			fprintf(stderr, "read: %d\n", i);
			fprintf(stderr, "buffer: %s\n", buf);
			#endif
                }
      }

	close(sockfd);

	return 0;
}

Categories: C/C++ 流媒体 网络

Tagged as:

lnmcc