分类: 2007-10-06 15:53 546人阅读 (0)
以前用WinInet的类写过网络爬虫,所以也想自己试着直接用socket来写一个类似程序,看了很多的例程以及文章,自己用WinSock写了一个http下get功能的程序,比较精简,基本体现了这类程序的框架,发现重点还是要了解好http协议的头部,准备进一步学习RFC文档,网上对于http协议的介绍都貌似比较简略。
--2007--10--6--by wangben--hit--程序是vc下的一个Windows console的工程:
#include <stdio.h>
#include <stdlib.h>#include <string.h>#include <winsock2.h> //header#pragma comment (lib, "ws2_32.lib") //libvoid SendString(SOCKET sock,LPCSTR str){ send(sock,str,strlen(str),0);}int main(void)
{ WSADATA wsaData; SOCKET sock; SOCKADDR_IN tcpaddr; hostent * remoteHost; char host[] = {"主机名就直接写了 int Ret,l; BOOL done; int port = 80; int chars = 0; char buffer[512];if( (Ret = WSAStartup(MAKEWORD(1,1), &wsaData) ) != 0 )
{ printf("WSAStartup failed with error %d/n", Ret); return 1; }if( (remoteHost = gethostbyname(host)) == NULL ) //通过主机名获取地址
{ printf("gethostbyname error!/n"); return 1; } sock = socket (AF_INET, SOCK_STREAM, 0); tcpaddr.sin_family = AF_INET; tcpaddr.sin_port = htons( (unsigned short)port ); tcpaddr.sin_addr.s_addr = *((unsigned long *)*remoteHost->h_addr_list); //转换地址if( connect(sock, (const sockaddr * )&tcpaddr, sizeof(tcpaddr)) )
{ printf("connect error!"); return 1; }//这里是要发送的http头部 SendString(sock,"GET / HTTP/1.1/r/n"); SendString(sock,"Host:www.hao123.com/r/n"); SendString(sock,"Accept: */*/r/n"); SendString(sock,"User-Agent: Mozilla/4.0"); SendString(sock,"(compatible; MSIE 5.00; Windows 98)/r/n"); SendString(sock,"Connection:Keep-Alive/r/n"); SendString(sock,"/r/n"); SendString(sock,"/r/n");//最后要加空行done = FALSE;
FILE * fp; fp = fopen("1.txt","w");//打印并保存http响应的头部 while(!done) { l = recv(sock,buffer,1,0); if(l<0) done=TRUE; switch(*buffer) { case '/r': break; case '/n': if(chars==0) done = TRUE; chars=0; break; default: chars++; break; } printf("%c",*buffer); fputc(buffer[0],fp); }//接收正文部分
int sum = 0; do { l = recv(sock,buffer,sizeof(buffer)-1,0); if( l < 0 ) break; sum += l; *(buffer + l) = 0; fputs(buffer,fp); } while( l > 0 ); //这里输出正文部分大小,发现其实和响应消息头部的Content-length大小是一样的//这样就可以检查是否接受完毕 printf("sum = %d/n",sum); closesocket(sock);if( WSACleanup() == SOCKET_ERROR )
{ printf("WSACleanup failed with error %d /n", WSAGetLastError() ); }return 0;
}