linux c 使用socket处理HTTP请求
31 Oct 2013
#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;
}