好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

使用C语言获取百度源代码

使用C语言获取百度源代码

使用C语言获取百度源代码

当我在单机世界摸爬滚打数月时,我也跟着时代的潮流,正式的跨入了网络化编程时代。学习一项新技术,永远是一件令人兴奋的事情。但是,想要找到一个好的学习教程无疑是一件困难的事情,搜寻百度谷歌无数次,终于踏入了Winsock的大门,我会在学习Windows网络编程中的心得体会发布出来,供大家学习。因为我也是新手,如果在博文当中有什么错误的地方,还请各位高手大大提出来,以帮助本人改正错误。

  如果你原来学习过Winsock编程,那么看本篇文章将会非常轻松。如果没学过,也没关系,本篇博文将会详细讲解。OK,废话不多说,直接跳到主题。

  1.在我们使用任何winsock函数之前,必须要现在头文件中添加winsock2.h和ws2_32.lib文件。

#include <winsock2.h>

 #pragma  comment(lib, "ws2_32.lib")

同时,我们要注意:winsock2.h头文件必须要放在windows.h头文件的上面,要不然编译的时候会出错。

  2.在我们调用任何winsock函数之前,还要必须通过WSAStartup函数完成对winsock服务的初始化。

 int  WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData )

(1)wVersionRequested:一个WORD(双字节)型数值,在最高版本的Windows Sockets支持调用者使用,高阶字节指定小版本(修订本)号,低位字节指定主版本号。一般使用MAKEWORD(2,2)

(2)lpWSAData 指向WSADATA数据结构的指针,用来接收Windows Sockets实现的细节。

  3.当我们调用了WSAStartup函数后,便可以调用其他的winsock函数了。使用WSASocket函数创建一个与指定服务提供者捆绑的套接字。

WSASocket( int  af,  int  type,  int  protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g, DWORD dwFlags);

(1)af:一个地址族规范,我们使用AF_INET。

(2)type:新套接字的类型描述,我们使用SOCK_STREAM,也就是使用TCP

(3)protocol:套接字使用的特定协议,如果调用者不愿指定协议则定为0

(4)lpProtocolInfo:一个指向PROTOCOL_INFO结构的指针,该结构定义所创建套接口的特性。如果本参数非零,则前三个参数(af, type, protocol)被忽略。

(5)g:保留给未来使用的套接字组。套接口组的标识符。

(6)dwFlags:套接口属性描述。

一般我们都是用前面三个,后面的都为NULL。如果成功,返回的是一个SOCKET类型的套接字。如果返回失败,则返回SOCKET_ERROR

  4.我们使用connect函数连接上我们指定的网站。

connect(SOCKET s,  const   struct  sockaddr FAR * name,  int  namelen);

(1)s:套接字描述符,也就是我们调用的WSASocket函数返回的套接字

(2)name:一个SOCKADDR类型,不过我们一般使用SOCKADDR_IN类型,也就是是我们需要连接的IP,端口等等

(3)namelen:SOCKADDR结构体的长度。

  SOCKADDR_IN ipconfig;
HOSTENT  *  iphost;
  char  * url =  "  baidu.com  "  ;

  if ((iphost = gethostbyname(url)) !=  NULL)
    ipconfig.sin_addr.S_un.S_addr  = inet_addr(inet_ntoa(*(( struct  in_addr *)iphost->h_addr_list[ 0  ])))
ipconfig.sin_port  = htons( 80  );
ipconfig.sin_family  = AF_INET; 

可以看我的另外一篇博文: 使用C语言获取指定域名的IP

  5.当我们连接以后,就需要发送http协议头信息了,如下:

 char  * httpHeader =  "  GET /index.html\r\nAccept: application/javascript, */*;q=0.8\r\nHost: baidu.com\r\nConnection: Keep-Alive\r\n\r\n  " 

然后使用send函数将其发送给主机。

send(sock, httpHeader, strlen(httpHeader) +  1 ,  0 )

  6.如果我们发送出去以后,需要使用recv函数进行接收从服务器返回过来的信息,其中,第一次返回的是服务器返回过来的HTTP头,我们可以从中看见是否成功,其后返回过来的则是网页的源代码:

 int  i =  0 , check, err =  0  ;
  char  recvChar[ 100  ];
  char  recvCDa[ 500  ];

  if (recv(sock, recvCDa,  500 ,  0 ) ==  SOCKET_ERROR)
    {
        fprintf(stderr,   "  返回信息失败,错误代码:%d  "  ,WSAGetLastError());

        system(  "  pause  "  );
          return   1  ;
    }
     printf(  "  服务器返回HTTP头:%s\n  "  , recvCDa);

     memset(recvChar,   '  \0  ' ,  101  );

       while ((check = recv(sock, recvChar,  sizeof (recvChar),  0 )) !=  SOCKET_ERROR)
    {
          if (check <  100  )
            err  =  1  ;
        printf(  "  %s  "  , recvChar);

        memset(recvChar,   0 ,  100  );

          if (err ==  1  )
              break  ;
        i ++ ;
    } 

OK,下面附上一段整体的获取百度源代码的代码:

#include <stdio.h> 
#include  < string.h > 
#include  <winsock2.h> 
#include  <Windows.h>

 #pragma  comment(lib, "ws2_32.lib")

 using   namespace   std;

  char  * urlIp( char  *  url);

  int  main( int  argc,  char  *  argv[])
{
    SOCKADDR_IN url_ipconfig  = { sizeof  (SOCKADDR_IN)};
      char  *  sendChar;
    WSADATA wsaDa;
    SOCKET sock;
      char  ip[ 20  ];
      char  sendString[ 100  ];
      char  recvChar[ 100  ];
       char  recvCDa[ 500  ];

      if (WSAStartup(MAKEWORD( 2 , 2 ), &wsaDa) ==  SOCKET_ERROR)
    {
        fprintf(stderr,   "  初始化WSAStartup出错,错误代码:%d  "  ,WSAGetLastError());

        system(  "  pause  "  );
          return   1  ;
    }

      if ((sock = WSASocket(AF_INET, SOCK_STREAM,  0 , NULL, NULL,  0 )) ==  SOCKET_ERROR)
    {
        fprintf(stderr,   "  初始化WSAStartup出错,错误代码:%d  "  ,WSAGetLastError());

        system(  "  pause  "  );
          return   1  ;
    }
    
    strcpy(ip, urlIp(  "  baidu.com  "  ));

    url_ipconfig.sin_family  =  AF_INET;
    url_ipconfig.sin_port  = htons( 80  );
    url_ipconfig.sin_addr.S_un.S_addr  =  inet_addr(ip);

      if (connect(sock, (SOCKADDR *)&url_ipconfig,  sizeof (url_ipconfig)) ==  SOCKET_ERROR)
    {
        fprintf(stderr,   "  连接服务器失败,错误代码:%d  "  ,WSAGetLastError());

        system(  "  pause  "  );
          return   1  ;
    }

    strcpy(sendString,   "  GET /index.html HTTP/1.1\r\nAccept: application/javascript, */*;q=0.8\r\nHost: baidu.com\r\nConnection: Keep-Alive\r\n\r\n  "  );

      if (send(sock, sendString, strlen(sendString) +  1 ,  0 ) ==  SOCKET_ERROR)
    {
        fprintf(stderr,   "  发送GET包失败失败,错误代码:%d\n  "  ,WSAGetLastError());

        system(  "  pause  "  );
          return   1  ;
    }

     memset(recvCDa,   '  \0  ' ,  500  );

       if (recv(sock, recvCDa,  500 ,  0 ) ==  SOCKET_ERROR)
    {
        fprintf(stderr,   "  返回信息失败,错误代码:%d  "  ,WSAGetLastError());

        system(  "  pause  "  );
          return   1  ;
    }
     printf(  "  %s\n  "  , recvCDa);

       int  i =  0 , check, err =  0  ;
     memset(recvChar,   '  \0  ' ,  101  );

       while ((check = recv(sock, recvChar,  sizeof (recvChar),  0 )) !=  SOCKET_ERROR)
    {
          if (check <  100  )
            err  =  1  ;
        printf(  "  %s  "  , recvChar);

        memset(recvChar,   0 ,  100  );

          if (err ==  1  )
              break  ;
        i ++ ;
    }
    system(  "  pause  "  );
      return   0  ;
}

  char  * urlIp( char  *  url)
{
    HOSTENT  *  iphost;
      char  ipconfig[ 20  ];
      char  ip[ 20  ];

      if ((iphost = gethostbyname(url)) !=  NULL)
    {
        memcpy( &ip, inet_ntoa(*(( struct  in_addr *)iphost->h_addr_list[ 0 ])),  20  );
    }

      return   ip;
} 

转载本文请注明来源:http://www.cnblogs.com/cnlyml。谢谢

 

分类:  Windows编程

标签:  Windows编程 ,  WinSocket ,  GET

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于使用C语言获取百度源代码的详细内容...

  阅读:48次

上一篇: Amazon下拉菜单

下一篇:装配线调度