用WinSock实现HTTP的GET Unicorn 博客频道 CSDN.NET

用WinSock实现HTTP的GET - Unicorn - 博客频道 - CSDN.NET


用WinSock实现HTTP的GET


分类:
VC++学习
C/C++学习点滴


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") //lib

void 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[] = {"www.hao123.com"};     //主机名就直接写了
 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;

原文地址:https://www.cnblogs.com/lexus/p/2616308.html