C++辅导:IPv6网络程序设计
来源:优易学  2011-9-10 17:07:03   【优易学:中国教育考试门户网】   资料下载   IT书店


  对于客户机来说,不管是建立TCP/UDP 连接,它都应知道服务器的主机名或IP 地址,同时将服务器地址解析为IPv4或IPv6地址都可以,一般可以考虑一下步骤:
  SOCKET s;
  struct addrinfo,hints,*res=NULL;
  char *szRemoteAddress;//主机名或IP 地址
  char *szRemotePort;//端口号
  int rc;
  1.用getaddrinfo() 函数解析地址。hins结构中 使用AF_UNSPEC标志,便可以获得地址簇类型(IPv4或IPv6)。
  memset(&hintas,0,sizeof(hints));
  hints.ai_family=AF_UNSPEC;
  hints.ai_socktype=SOCK_STREAM;
  hints.ai_protocol=IPPROTO_TCP;
  rc=getaddrinfo(szRemoteAdddress,szRemotePort,&hints,&res);
  if(rc==WSANO_DATA)
  {// 无法解析,出错
  }
  用返回的addrinfo结构中的ai_family,ai_socketype,ai_protocol字段来创建套接字。
  s=socket(res->ai_family,ai_socktype,res->protocol);
  if(s==INVALID_SOCKET)
  {//创建套接字失败
  }
  2.使用返回的addrinfo结构中的ai_addr来调用其他函数(connect(),send()等).。
  rc==connect(s,res->ai_addr,res->addrlen);
  if(rc==SOCKET_ERROR)
  {//连接失败;
  }
  。。。//完成其他编程
  <二>服务器程序设计
  服务器程序设计,应考虑到IPv4和IPv6 都具有各自的堆栈;因此如果服务器希望能同时接受IPv4和IPv6的连接,就必须能同时创建IPv4和IPv6套接字;一般可以考虑一下步骤:
  SOCKET socklisten[2];//监听Socket变量
  char *szPort=”8080”;//监听端口
  struct addinfo hints,*res=NULL,*ptr=NULL;
  int rc,i=0;
  1. 调用getaddrinfo()函数,该结构包含AI_PASSIVE,AF_UNSPEC标志,以及所需的套接字类型、协议及所需的本地端口(用来监听和接受数据等)。函数将返回的两个addrinfo结构,分别可用于IPv4和IPv6监听地址:

 memset(&hints,0,sizeof(hints));
  hints.ai_family=AF_UNSPEC;
  hints.ai_socktype=SOCK_STREAM;
  hints.ai_protocol=IPPROTO_TCP;
  hints.ai_flags=AI_PASSIVE;
  rc=getaddinfo(NULL,szPort,&hints,&res);
  if(rc!=0){//失败处理;}
  ptr=res;
  2. 用返回的addrinfo结构中的ai_family,ai_socketype,ai_protocol字段来创建套接字后;便可以使用addrinfo结构中的ai_addr 和ar_addrlen 字段调用绑定函数bind()。
  while(ptr)
  {
  socklisten[i]=socket(ptr->ai_family,ptr->ai_socktype,ptr->ai_protocol);
  if(socklisten[i]==INVALID_SOCKET){//创建失败处理;}
  rc=bind(socklisten[i],ptr->ai_addr,ptr->ai_addrlen);
  if(rc==SOCKET_ERROR){//绑定失败处理}
  rc=listen(slisten[i],7)//开始监听
  if(rc==SOCKET_ERROR){//监听失败处理}
  i++;
  ptr=ptr->ai_next;
  }
  。。。
  //完成其他编程
  五、程序实例
  在这里,给出一个基于IPV6的简单回应(ECHO)服务器程序.
  1.建立CIPv6 类
  // IPv6.h: 头文件,这里使用到了套接字中的“select I/O模型”
  #define WIN32_LEAN_AND_MEAN
  #include <winsock2.h>
  #include <ws2tcpip.h>
  #include <tpipv6.h>//IPv6 头文件
  #include <stdlib.h>
  #include <stdio.h>
  #include <string.h>
  #pragma comment(lib, "ws2_32.lib")//套接字库文件
  #define DEFAULT_PORT "7274" // 默认端口
  #define BUFFER_SIZE 64 // 数据缓冲区
  class CIPv6
  {
  public:
  // 创建TCP 服务器
  int CreateServer(char *Port = DEFAULT_PORT,char *Address = NULL);
  void Usage(char *ProgName);//用户信息提示
  LPSTR DecodeError(int ErrorCode);//获取错误信息
  CIPv6();
  virtual ~CIPv6();
  };
  // IPv61.cpp: CIPv6类的实现 .
  // IPv61.cpp: implementation of the CIPv6 class.
  //

 //////////////////////////////////////////////////////////////////////
  #include "stdafx.h"
  #include "IPv61.h"
  int CIPv6::CreateServer(char *Port, char *Address)
  {
  char Buffer[BUFFER_SIZE], Hostname[NI_MAXHOST];
  int RetVal, FromLen, AmountRead;
  SOCKADDR_STORAGE From;
  WSADATA wsaData;
  ADDRINFO Hints, *AddrInfo;
  SOCKET ServSock;
  fd_set SockSet;
  // 启动Winsock
  if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
  {
  fprintf(stderr, "WSAStartup failed with error %d: %s\n",
  RetVal, DecodeError(RetVal));
  WSACleanup();
  return -1;
  }
  if (Port == NULL)
  {
  Usage("Port Error");
  }
  memset(&Hints, 0, sizeof(Hints));
  Hints.ai_family =AF_INET6;// Family;
  Hints.ai_socktype =SOCK_STREAM;
  Hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
  RetVal = getaddrinfo(Address, Port, &Hints, &AddrInfo);
  if (RetVal != 0)
  {
  fprintf(stderr, "getaddrinfo failed with error %d: %s\n", RetVal, gai_strerror(RetVal));
  WSACleanup();
  return -1;
  }
  // 创建套接字
  ServSock = socket(AddrInfo->ai_family,AddrInfo->ai_socktype, AddrInfo->ai_protocol);
  if (ServSock == INVALID_SOCKET)
  {

上一页  [1] [2] [3] 下一页

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训