网站导航:首页 -> 软件水平考试 -> 软件水平考试指导 -> Socket编程相关数据类型定义

Socket编程相关数据类型定义

计算机数据存储有两种字节优先顺序:高位字节优先和低位字节优先。internet上数据以高位字节优先顺序在网络上传输,所以对于在内部是以低位字节优先方式存储数据的机器,在internet上传输数据时就需要进行转换。 
  我们要讨论的第一个结构类型是:struct sockaddr,该类型是用来保存socket信息的: 
  struct sockaddr { 
  uns [被屏蔽广告]igned short sa_family; /* 地址族, af_xxx */ 
  char sa_data[14]; /* 14 字节的协议地址 */ }; 
  sa_family一般为af_inet;sa_data则包含该socket的ip地址和端口号。 
  另外还有一种结构类型: 
  struct sockaddr_in { 
   short int sin_family; /* 地址族 */ 
   unsigned short int sin_port; /* 端口号 */ 
   struct in_addr sin_addr; /* ip地址 */ 
   unsigned char sin_zero[8]; /* 填充0 以保持与struct sockaddr同样大小 */ 
  }; 
  这个结构使用更为方便。sin_zero(它用来将sockaddr_in结构填充到与struct sockaddr同样的长度)应该用bzero()或memset()函数将其置为零。指向sockaddr_in 的指针和指向sockaddr的指针可以相互转换,这意味着如果一个函数所需参数类型是sockaddr时,你可以在函数调用的时候将一个指向sockaddr_in的指针转换为指向sockaddr的指针;或者相反。sin_family通常被赋af_inet;sin_port和sin_addr应该转换成为网络字节优先顺序;而sin_addr则不需要转换。 
  我们下面讨论几个字节顺序转换函数: 
  htons()--'host to network short' ; htonl()--'host to network long' 
  ntohs()--'network to host short' ; ntohl()--'network to host long' 
  在这里, h表示'host' ,n表示'network',s 表示'short',l表示 'long'。 
  打开socket 描述符、建立绑定并建立连接 
  socket函数原型为: 
  int socket(int domain, int type, int protocol); 
  domain参数指定socket的类型:sock_stream 或sock_dgram;protocol通常赋值“0”。socket()调用返回一个整型socket描述符,你可以在后面的调用使用它。 
  一旦通过socket调用返回一个socket描述符,你应该将该socket与你本机上的一个端口相关联(往往当你在设计服务器端程序时需要调用该函数。随后你就可以在该端口监听服务请求;而客户端一般无须调用该函数)。 bind函数原型为: 
  int bind(int sockfd,struct sockaddr *my_addr, int addrlen); 
  sockfd是一个socket描述符,my_addr是一个指向包含有本机ip地址及端口号等信息的sockaddr类型的指针;addrlen常被设置为sizeof(struct sockaddr)。 
  最后,对于bind 函数要说明的一点是,你可以用下面的赋值实现自动获得本机ip地址和随机获取一个没有被占用的端口号: 
  my_addr.sin_port = 0; /* 系统随机选择一个未被使用的端口号 */ 
  my_addr.sin_addr.s_addr = inaddr_any; /* 填入本机ip地址 */ 
  通过将my_addr.sin_port置为0,函数会自动为你选择一个未占用的端口来使用。同样,通过将my_addr.sin_addr.s_addr置为inaddr_any,系统会自动填入本机ip地址。bind()函数在成功被调用时返回0;遇到错误时返回“-1”并将errno置为相应的错误号。另外要注意的是,当调用函数时,一般不要将端口号置为小于1024的值,因为1~1024是保留端口号,你可以使用大于1024中任何一个没有被占用的端口号。