c语言写下载网页的程序,C语言实现下载网页的方法【原创】

Author:张继飞

这些日子由于要做RSS订阅,想把服务器端的XML文件下载到本地,这样解析起来更加方便,呵呵。所以使用socket做一个向服务器请求下载网页的功能,参考了网上一些代码,终于实现了。哈哈哈。

环境:linux

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAXHEADERSIZE 1024

#define true 0

#define false -1

char m_requestheader[1024];

char m_ResponseHeader[1024];

int m_port = 80;

char m_ipaddr[256];

int m_bConnected = 0;

int m_s = -1;

struct hostent *m_phostent = NULL;

int m_nCurIndex = 0;

int m_bResponsed = 0;

int m_nResponseHeaderSize = -1;

int GetServerState();

int GetField(const char* szSession,char *szValue);

int GetResponseLine(char *pLine,int nMaxLength);

const char *GetResponseHeader(int Length);

long FormatRequestHeader(char *pServer,char *pObject,char* pCookie,char *pReferer,long nFrom,long nTo,int nServerType);

const int GetRequestHeader(char *pHeader,int nMaxLength);

int SendRequest(const char* pRequestHeader,long Length);

long Receive(char* pBuffer,long nMaxLength);

int Connect(char* szHostName,int nPort);

int CloseSocket();

int Socket();

int main(void)

{

int i;

FILE *stream;

for(i=0;i<256;i++)

m_ipaddr[i]='\0';

memset(m_requestheader,0,MAXHEADERSIZE);

memset(m_ResponseHeader,0,MAXHEADERSIZE);

char *strServer = "rss.news.yahoo.com";

char *strObject = "/rss/terrorism";

long nLength;

//AfxParseURL("http://rss.news.yahoo.com/rss/terrorism",dwServiceType,strServer,strObject,nPort);

nLength = FormatRequestHeader(strServer,strObject,NULL,NULL,0,0,0);

Socket();

Connect(strServer,80);

SendRequest(NULL,0);

char szValue[30];

GetField("Content-Length",szValue);

int nFileSize = atoi(szValue);

int nCompletedSize = 0;

char pData[1024];

int nReceSize = 0;

if ((stream = fopen("rss.xml", "w+")) == NULL)

{

printf("can not open file");

}

while((nCompletedSize < nFileSize) && (stream != NULL))

{

nReceSize = Receive(pData,1024);

if(nReceSize == 0)

{

printf("receive from server only 0!\n");

break;

}

else if(nReceSize == -1)

{

printf("receive from server error!\n");

break;

}

else

{

fwrite(pData, nReceSize, 1, stream);

printf("strlen(pData) = %d\n",strlen(pData));

}

printf("size = %d\n",nReceSize);

}

fclose(stream);

CloseSocket();

return 0;

}

int Socket()

{

if(m_bConnected)return false;

m_s=socket(AF_INET,SOCK_STREAM,0);

printf("m_s %d\n",m_s);

if(m_s==-1)

{

printf("open socket error!\n");

return false;

}

return true;

}

int Connect(char *szHostName,int nPort)

{

if(szHostName==NULL)

return false;

if(m_bConnected)

{

CloseSocket();

}

m_port=nPort;

m_phostent=gethostbyname(szHostName);

if(m_phostent==NULL)

{

printf("gethostbyname error!\n");

return false;

}

/* struct in_addr ip_addr;

memcpy(&ip_addr.s_addr,m_phostent->h_addr_list[0],4);

serv_addr.sin_addr = *((struct in_addr *)host->h_addr)*/

struct sockaddr_in destaddr;

memset((void *)&destaddr,0,sizeof(destaddr));

destaddr.sin_family=AF_INET;

destaddr.sin_port=htons(80);

destaddr.sin_addr=*((struct in_addr *)m_phostent->h_addr);//必须包含#include

printf("ms = %d\n",m_s);

if(connect(m_s,(struct sockaddr*)&destaddr,sizeof(struct sockaddr))==-1)

{

//CloseSocket();

//m_s=NULL;

printf("Can not connect!\n");

return false;

}

m_bConnected=1;

return true;

}

long FormatRequestHeader(char *pServer,char *pObject, char *pCookie,char *pReferer,long nFrom,long nTo,int nServerType)

{

char szPort[10];

char szTemp[20];

long Length;

sprintf(szPort,"%d",m_port);

memset(m_requestheader,'\0',1024);

strcat(m_requestheader,"GET ");

strcat(m_requestheader,pObject);

strcat(m_requestheader," HTTP/1.1");

strcat(m_requestheader,"\r\n");

strcat(m_requestheader,"Host:");

strcat(m_requestheader,pServer);

strcat(m_requestheader,"\r\n");

if(pReferer != NULL)

{

strcat(m_requestheader,"Referer:");

strcat(m_requestheader,pReferer);

strcat(m_requestheader,"\r\n");

}

strcat(m_requestheader,"Accept:*/*");

strcat(m_requestheader,"\r\n");

strcat(m_requestheader,"User-Agent:Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)");

strcat(m_requestheader,"\r\n");

strcat(m_requestheader,"Connection:Keep-Alive");

strcat(m_requestheader,"\r\n");

strcat(m_requestheader,"\r\n");

Length=strlen(m_requestheader);

return Length;

}

int SendRequest(const char *pRequestHeader, long Length)

{

if(!m_bConnected)return false;

if(pRequestHeader==NULL)

pRequestHeader=m_requestheader;

if(Length==0)

Length=strlen(m_requestheader);

if(send(m_s,pRequestHeader,Length,0)==-1)

{

printf("send error\n");

return false;

}

printf("send ok\n");

int nLength;

GetResponseHeader(nLength);

return true;

}

long Receive(char* pBuffer,long nMaxLength)

{

if(!m_bConnected)return -1;

long nLength;

nLength=recv(m_s,pBuffer,nMaxLength,0);

if(nLength <= 0)

{

printf("receive error! %d\n",nLength);

CloseSocket();

}

return nLength;

}

int CloseSocket()

{

if(m_s != -1)

{

if(close(m_s)==-1)

{

printf("closesocket error!\n");

return false;

}

}

m_s = -1;

m_bConnected=0;

return true;

}

const int GetRequestHeader(char *pHeader, int nMaxLength)

{

int nLength;

if((strlen(m_requestheader))>nMaxLength)

{

nLength=nMaxLength;

}

else

{

nLength=strlen(m_requestheader);

}

memcpy(pHeader,m_requestheader,nLength);

return nLength;

}

const char *GetResponseHeader(int nLength)

{

if(!m_bResponsed)

{

char c = 0;

int nIndex = 0;

int bEndResponse = 0;

while(!bEndResponse && nIndex < MAXHEADERSIZE)

{

recv(m_s,&c,1,0);

m_ResponseHeader[nIndex++] = c;

if(nIndex >= 4)

{

if(m_ResponseHeader[nIndex - 4] == '\r' && m_ResponseHeader[nIndex - 3] == '\n'

&& m_ResponseHeader[nIndex - 2] == '\r' && m_ResponseHeader[nIndex - 1] == '\n')

bEndResponse = 1;

}

}

m_nResponseHeaderSize = nIndex;

m_bResponsed = 1;

}

printf("response length =%d\n",m_nResponseHeaderSize);

printf("response content =%s\n",m_ResponseHeader);

nLength = m_nResponseHeaderSize;

return m_ResponseHeader;

}

int GetResponseLine(char *pLine, int nMaxLength)

{

if(m_nCurIndex >= m_nResponseHeaderSize)

{

m_nCurIndex = 0;

return -1;

}

int nIndex = 0;

char c = 0;

do

{

c = m_ResponseHeader[m_nCurIndex++];

pLine[nIndex++] = c;

} while(c != '\n' && m_nCurIndex < m_nResponseHeaderSize && nIndex < nMaxLength);

return nIndex;

}

int GetField(const char *szSession, char *szValue)

{

if(!m_bResponsed) return -1;

printf("GetField\n");

char strRespons[1024];

strcpy(strRespons, m_ResponseHeader);

char *p = NULL;

p = strtok(strRespons, "\r\n");

while(p)

{

if (0 == strncmp(p, szSession, 14))

{

strcpy(szValue,p+16);

printf("Content-Length: %s\n",szValue);

break;

}

else

{

printf("no Content-Length\n");

p = strtok(NULL, "\r\n");

}

}

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值