winsock 发送http请求
使用winsock来尝试下载html文件,但对于图片二进制文件接收还有问题 很不稳定
#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
#include <string.h>
#pragma comment(lib,"ws2_32.lib")
#define USERAGENT "Mozilla/5.0 "
#define BUFFSIZE (6000)
SOCKET HTTPConnectToServer(char* server){
SOCKADDR_IN serverInfo;
SOCKET sck;
WSADATA wsaData;
hostent* hostEntry;
char* serverIP;
WSAStartup(MAKEWORD(2,2),&wsaData);
hostEntry = gethostbyname(server);
if(!hostEntry){ //获取服务器端信息
WSACleanup();
return 0;
}
serverIP = inet_ntoa(*(struct in_addr *)*hostEntry->h_addr_list);
printf(serverIP);//显示服务器ip from MSDN
//create socket
sck = socket(AF_INET,SOCK_STREAM,0);
if(sck==INVALID_SOCKET){
WSACleanup();
puts("Failed to setup socket");
getchar();
return 0;
}
// Set up the sockaddr structure
serverInfo.sin_family = AF_INET;
serverInfo.sin_addr.s_addr = inet_addr(serverIP);
serverInfo.sin_port = htons(80);
int TimeOut=4000; //收发超时4秒
if(SOCKET_ERROR== setsockopt(sck,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut)))
{
perror("Can't set timeout!");
}
//连接
int i = connect(sck,(LPSOCKADDR)&serverInfo,sizeof(struct sockaddr));
if(sck==SOCKET_ERROR) return 0;
if(i!=0) return 0;
return sck;
}
//page 为请求地址 / , host 为请求的主机
void HTTPRequestPage(char *host, char *page, char *filename){
SOCKET sock;
char buf[BUFFSIZE+1];
char *getpage = page;
char *query;
char *tpl = "GET /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n";
if (getpage[0]=='/')
{
getpage = getpage + 1;
fprintf(stderr,"Removing leading \"/\", converting %s to %s\n", page, getpage);
}
// -5 is to consider the %s %s %s in tpl and the ending \0
query = (char *)malloc(strlen(host)+strlen(getpage)+strlen(USERAGENT)+strlen(tpl)-5);
sprintf(query,tpl,getpage,host,USERAGENT);
fprintf(stderr, "Query is:\n<<START>>\n%s<<END>>\n", query);
//create connection
sock = HTTPConnectToServer(host);
//发送请求
int tmpres;
int sent = 0;
while (sent<strlen(query))
{
tmpres = send(sock,query+sent, strlen(query)-sent,0);
if (tmpres == -1)
{
perror("Can't send query");
exit(1);
}
sent+=tmpres;
}
//open file to save
FILE *file_out;
if ((file_out=fopen(filename,"w+"))==NULL)
{
printf("File open error!");
}
//receive page
memset(buf, 0, sizeof(buf));
int htmlstart = 0;
char *htmlcontent= 0;
while ((tmpres = recv(sock,buf,BUFFSIZE,0))>0)
{//If the \r\n\r\n part is splitted into two messages
if (htmlstart==0)//it will fail to detect the beginning of HTML content
{
htmlcontent = strstr(buf,"\r\n\r\n");
if (htmlcontent!=NULL)
{
htmlstart = 1;
htmlcontent += 4;
}
}else{
htmlcontent = buf;
}
if (htmlstart)
{
fprintf(file_out,htmlcontent);
//fwrite(htmlcontent,sizeof(char),buf+tmpres-htmlcontent,file_out);
printf("\n%d,\t%d\n",tmpres,sizeof(buf));
}
memset(buf, 0, tmpres);
}
if (tmpres<0)
{
perror("Error receiving data");
}
printf("write to file successfully!");
free(query);
fclose(file_out);
closesocket(sock);
}
//Parse url into host and page
void URLParse(char *url,char **host, char **page){
unsigned short shift=0;
if(strncmp(url,"http://",strlen("http://"))==0){
shift=strlen("http://");// 判断地址前是否有http://
}
//VC 使用k&R C如果改为main.c 则下面一句提示标识符未定义
char *cut=(char*)malloc(strlen(url)-shift+1);
strcpy(cut,strdup(url+shift)); //strdup复制字符串webpage+shift,即除了http://www.
//取得host的域名如baidu.com
*host = strtok(cut,"/");//分解字符串为一组字符串。cut 为要分解的字符串,/为分隔符字符串。
*page = strdup(url+shift+strlen(*host));// 主机名后/之后的字符串 包括"/"
}
int main(int argc,char *argv[]){
char *host,*page;
URLParse("www.baidu.com",&host,&page);
printf("Host: %s\nPage: %s\n",host, page);
HTTPRequestPage(host, page,"baidu.html");
free(host);
free(page);
return 0;
}
#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
#include <string.h>
#pragma comment(lib,"ws2_32.lib")
#define USERAGENT "Mozilla/5.0 "
#define BUFFSIZE (6000)
SOCKET HTTPConnectToServer(char* server){
SOCKADDR_IN serverInfo;
SOCKET sck;
WSADATA wsaData;
hostent* hostEntry;
char* serverIP;
WSAStartup(MAKEWORD(2,2),&wsaData);
hostEntry = gethostbyname(server);
if(!hostEntry){ //获取服务器端信息
WSACleanup();
return 0;
}
serverIP = inet_ntoa(*(struct in_addr *)*hostEntry->h_addr_list);
printf(serverIP);//显示服务器ip from MSDN
//create socket
sck = socket(AF_INET,SOCK_STREAM,0);
if(sck==INVALID_SOCKET){
WSACleanup();
puts("Failed to setup socket");
getchar();
return 0;
}
// Set up the sockaddr structure
serverInfo.sin_family = AF_INET;
serverInfo.sin_addr.s_addr = inet_addr(serverIP);
serverInfo.sin_port = htons(80);
int TimeOut=4000; //收发超时4秒
if(SOCKET_ERROR== setsockopt(sck,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut)))
{
perror("Can't set timeout!");
}
//连接
int i = connect(sck,(LPSOCKADDR)&serverInfo,sizeof(struct sockaddr));
if(sck==SOCKET_ERROR) return 0;
if(i!=0) return 0;
return sck;
}
//page 为请求地址 / , host 为请求的主机
void HTTPRequestPage(char *host, char *page, char *filename){
SOCKET sock;
char buf[BUFFSIZE+1];
char *getpage = page;
char *query;
char *tpl = "GET /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n";
if (getpage[0]=='/')
{
getpage = getpage + 1;
fprintf(stderr,"Removing leading \"/\", converting %s to %s\n", page, getpage);
}
// -5 is to consider the %s %s %s in tpl and the ending \0
query = (char *)malloc(strlen(host)+strlen(getpage)+strlen(USERAGENT)+strlen(tpl)-5);
sprintf(query,tpl,getpage,host,USERAGENT);
fprintf(stderr, "Query is:\n<<START>>\n%s<<END>>\n", query);
//create connection
sock = HTTPConnectToServer(host);
//发送请求
int tmpres;
int sent = 0;
while (sent<strlen(query))
{
tmpres = send(sock,query+sent, strlen(query)-sent,0);
if (tmpres == -1)
{
perror("Can't send query");
exit(1);
}
sent+=tmpres;
}
//open file to save
FILE *file_out;
if ((file_out=fopen(filename,"w+"))==NULL)
{
printf("File open error!");
}
//receive page
memset(buf, 0, sizeof(buf));
int htmlstart = 0;
char *htmlcontent= 0;
while ((tmpres = recv(sock,buf,BUFFSIZE,0))>0)
{//If the \r\n\r\n part is splitted into two messages
if (htmlstart==0)//it will fail to detect the beginning of HTML content
{
htmlcontent = strstr(buf,"\r\n\r\n");
if (htmlcontent!=NULL)
{
htmlstart = 1;
htmlcontent += 4;
}
}else{
htmlcontent = buf;
}
if (htmlstart)
{
fprintf(file_out,htmlcontent);
//fwrite(htmlcontent,sizeof(char),buf+tmpres-htmlcontent,file_out);
printf("\n%d,\t%d\n",tmpres,sizeof(buf));
}
memset(buf, 0, tmpres);
}
if (tmpres<0)
{
perror("Error receiving data");
}
printf("write to file successfully!");
free(query);
fclose(file_out);
closesocket(sock);
}
//Parse url into host and page
void URLParse(char *url,char **host, char **page){
unsigned short shift=0;
if(strncmp(url,"http://",strlen("http://"))==0){
shift=strlen("http://");// 判断地址前是否有http://
}
//VC 使用k&R C如果改为main.c 则下面一句提示标识符未定义
char *cut=(char*)malloc(strlen(url)-shift+1);
strcpy(cut,strdup(url+shift)); //strdup复制字符串webpage+shift,即除了http://www.
//取得host的域名如baidu.com
*host = strtok(cut,"/");//分解字符串为一组字符串。cut 为要分解的字符串,/为分隔符字符串。
*page = strdup(url+shift+strlen(*host));// 主机名后/之后的字符串 包括"/"
}
int main(int argc,char *argv[]){
char *host,*page;
URLParse("www.baidu.com",&host,&page);
printf("Host: %s\nPage: %s\n",host, page);
HTTPRequestPage(host, page,"baidu.html");
free(host);
free(page);
return 0;
}
本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。