vc socket api建立TCP连接(包括域名解析)并收发数据的代码模板

vc socket api建立TCP连接(包括域名解析)并收发数据的代码模板
2009年11月26日
  VC和服务器建立TCP连接不像VB的winsock那样两三行代码就能搞定。虽然VC得MFC类库中也有CSocket、CAsyncSocket这样的类,但是这些类的毛病太多,还是返璞归真用socket api来的灵活。
  每次用到都得查一遍流程,这次写个几乎通用的模板,以备以后用。
  注:
  1.因为socket只能传入IP地址,所以要想连接还得先解析域名,以下包括把域名解析为IP的代码。
  2.以下代码为阻塞模式(并非异步模式)所以在主线程中使用很可能阻塞程序运行,最好是新开个线程使用。
  int retVal;
  WORD wVersionRequested;
  WSADATA wsaData;
  int err;
  //构建保存版本号的WORD类型变量
  wVersionRequested = MAKEWORD( 1, 1 );
  //加载套接字库
  err = WSAStartup( wVersionRequested, &wsaData );
  if ( err != 0 ) {
  return 0;
  }
  //检查加载的套接字库版本和请求的是否一致
  if ( LOBYTE( wsaData.wVersion ) != 1 ||
  HIBYTE( wsaData.wVersion ) != 1 ) {
  WSACleanup( );
  return 0;
  }
  //定义DWORD类型变量dwIP 该变量保存解析得到的IP地址(32位整数 并非点分十进制字符串)
  DWORD dwIP = 0;
  //域名解析
  HOSTENT* pHS = gethostbyname(strdomain);
  if( pHS != NULL)
  {
  in_addr addr;
  CopyMemory(&addr.S_un.S_addr, pHS->h_addr_list[0], pHS->h_length);
  dwIP = addr.S_un.S_addr;
  }
  else
  {
  WSACleanup();
  return 0;
  }
  //创建套接字,第一个参数是地址族 TCP/IP下始终为AF_INET,第二个参数表示流式套接字,第三个参数指定协议,0表示系统自选协议 而对于流式套接字 系统的自选协议就是TCP协议
  SOCKET sckTongJi = socket(AF_INET, SOCK_STREAM, 0);
  //定义地址结构体 并初始化
  SOCKADDR_IN addrSvr;
  addrSvr.sin_family = AF_INET;
  addrSvr.sin_addr.S_un.S_addr = dwIP; //inet_addr("127.0.0.1"); //字符串转十六进制IP用inet_addr反之用inet_ntoa
  addrSvr.sin_port = htons(80); //使用网络字序 不同处理器高位在前 还是 低位在前不相同 在这儿统一
  retVal = connect(sckTongJi, (SOCKADDR*)&addrSvr, sizeof(SOCKADDR_IN));
  if (retVal)
  {
  //AfxMessageBox("connect error!");
  WSACleanup();
  return 0;
  }
  char strbuff[4096];
  memset(strbuff, 0, sizeof(strbuff));
  send(sckTongJi, strout, strout.GetLength(), 0);
  recv(sckTongJi, strbuff, 4096, 0);
  closesocket(sckTongJi);
  WSACleanup();
  使用gethostbyname由域名或主机名得IP地址
  使用这个东西,首先要包含2个头文件:
  #include
  #include
  struct hostent *gethostbyname(const char *name);
  这个函数的传入值是域名或者主机名,例如"www.google.cn","wpc"等等。
  传出值,是一个hostent的结构(如下)。如果函数调用失败,将返回NULL。
  struct hostent
  {
  char *h_name;
  char **h_aliases;
  int h_addrtype;
  int h_length;
  char **h_addr_list;
  };
  解释一下这个结构:
  其中,
  char *h_name 表示的是主机的规范名。例如www.google.com的规范名其实是www.l.google.com。
  char **h_aliases 表示的是主机的别名.www.google.com就是google他自己的别名。有的时候,有的主机可能有好几个别名,这些,其实都是为了易于用户记忆而为自己的网站多取的名字。
  int h_addrtype 表示的是主机ip地址的类型,到底是ipv4(AF_INET),还是pv6(AF_INET6)
  int h_length 表示的是主机ip地址的长度
  int **h_addr_lisst 表示的是主机的ip地址,注意,这个是以网络字节序存储的。千万不要直接用printf带%s参数来打这个东西,会有问题的哇。所以到真正需要打印出这个IP的话,需要调用inet_ntop()。
  const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) :
  这个函数,是将类型为af的网络地址结构src,转换成主机序的字符串形式,存放在长度为cnt的字符串中。
  这个函数,其实就是返回指向dst的一个指针。如果函数调用错误,返回值是NULL。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值