C++写的socket网络爬虫(五)

2014-04-06 17:35:03 · 作者: · 浏览: 437

 

  二.makeSocket函数

  int makeSocket(string host,int port)

  {

  WSADATA inet_WsaData;//1

  WSAStartup(MAKEWORD(2, 0), &inet_WsaData);//1

  if (LOBYTE(inet_WsaData.wVersion) != 2 || HIBYTE(inet_WsaData.wVersion) != 0)//1

  {

  WSACleanup();

  return -1;

  }

  int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);//1

  struct hostent * hp = ::gethostbyname(host.c_str());//2

  struct sockaddr_in saddr;

  saddr.sin_family = AF_INET;

  saddr.sin_port = htons(port);

  memcpy(&saddr.sin_addr, hp->h_addr, 4);//3

  if (connect(tcp_socket, (const struct sockaddr *)&saddr, sizeof(saddr)) == -1)//1

  {

  cerr << "error in connect" << endl;

  }

  return tcp_socket;

  }

  1 见http://www.cnblogs.com/magicsoar/p/3585129.html windows下的C++ socket服务器(3)中讲解

  2 struct hostent * hp = ::gethostbyname(host.c_str());

  gethostbyname()返回对应于给定主机名的包含主机名字和地址信息的hostent结构指针

  hostent结构体的定义如下

  struct hostent {

  char FAR * h_name; /* official name of host */

  char FAR * FAR * h_aliases; /* alias list */

  short h_addrtype; /* host address type */

  short h_length; /* length of address */

  char FAR * FAR * h_addr_list; /* list of addresses */

  #define h_addr h_addr_list[0] /* address, for backward compat */

  };

  hostent->h_name 表示的是主机的规范名。例如www.baidu.com的规范名其实是www.a.shifen.com。(关于www.a.shifen.com还有一段故事http://www.zhihu.com/question/20100901)

  hostent->h_aliases 表示的是主机的别名.www.google.com就是google他自己的别名。有的时候,有的主机可能有好几个别名,这些,其实都是为了易于用户记忆而为自己的网站多取的名字。

  hostent->h_addrtype 表示的是主机ip地址的类型,到底是ipv4(AF_INET),还是pv6(AF_INET6)

  hostent->h_length 表示的是主机ip地址的长度

  hostent->h_addr_list 表示的是主机的ip地址

  #define h_addr h_addr_list[0]

  3 memcpy(&saddr.sin_addr, hp->h_addr, 4);

  由于 hp->h_addr是char*类型,不能直接赋值给saddr.sin_addr

  所以我们使用了memcpy函数

  函数原型如下

  void *memcpy(void *dest, const void *src, size_t n);

  从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。