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;
}