sockaddr结构体

sockaddr的缺陷: struct sockaddr 是一个通用地址结构,这是为了统一地址结构的表示方法,统一接口函数,使不同的地址结构可以被bind() , connect() 等函数调用;sa_data把目标地址和端口信息混在一起了

struct sockaddr {  
     unsigned short sa_family;
   char sa_data[14];                  
   }; 
sa_family是通信类型,最常用的值是 "AF_INET"
sa_data14字节,包含套接字中的目标地址和端口信息

sockaddr_in 结构体:struct sockaddr_in中的in 表示internet,就是网络地址,这只是我们比较常用的地址结构,属于AF_INET地址族,他非常的常用
sockaddr_in结构体解决了sockaddr的缺陷,把port和addr 分开储存在两个变量中

struct sockaddr_in { 
   short int sin_family;
   unsigned short int sin_port; 
     struct in_addr sin_addr;

struct in_addr { 
    unsigned long s_addr;
           }

unsigned char sin_zero[8];
}   

sin_port和sin_addr都必须是NBO
一般可视化的数字都是HBO(本机字节顺序)

sin_zero 初始值应该使用函数 bzero() 来全部置零。
   一般采用下面语句

struct sockaddr_in cliaddr;
bzero(&cliaddr,sizeof(cliaddr));

sockaddr_in结构体变量的基本配置

struct sockaddr_in ina;

bzero(&ina,sizeof(ina));

ina.sin_family=AF_INET;

ina.sin_port=htons(23);
ina.sin_addr.s_addr = inet_addr("132.241.5.10");  

sockaddr 和 sockaddr_in的相互关系
一般先把sockaddr_in变量赋值后,强制类型转换后传入用sockaddr做参数的函数

  • sockaddr_in用于socket定义和赋值
  • sockaddr用于函数参数

最典型的源、目的节点socket定义
对于源、目的地址和源、目的地址端口,需要建立两个socket变量
cliaddr绑定源地址和源端口
servaddr用于connect和sendto的设定目的地址和目的端口

struct sockaddr_in servaddr,cliaddr;

create_socket(char *server_addr_string,unsigned int server_port)
{
源socket赋值
       bzero(&cliaddr,sizeof(cliaddr));
       cliaddr.sin_family = AF_INET;
       通常TCP/UDP 协议源地址和端口都是随机的
       cliaddr.sin_addr.s_addr = htons(INADDR_ANY);
       cliaddr.sin_port = htons(0);

目的socket赋值
       bzero(&servaddr,sizeof(servaddr));
       servaddr.sin_family = AF_INET;
       inet_aton(server_addr_string,&servaddr.sin_addr);
       servaddr.sin_port = htons(server_port);
}

网络字节顺序 (Network Byte Order)      NBO
结构体的sin_port和sin_addr都必须是NBO

本机字节顺序 (Host Byte Order)    HBO
一般可视化的数字都是HBO

NBO,HBO二者转换
inet_addr()    将字符串点数格式地址转化成无符号长整型(unsigned long s_addr s_addr;)
inet_aton()    将字符串点数格式地址转化成NBO
inet_ntoa ()     将NBO地址转化成字符串点数格式
htons()    "Host to Network Short"
htonl()    "Host to Network Long"
ntohs()    "Network to Host Short"
ntohl()    "Network to Host Long"
常用的是htons(),inet_addr()正好对应结构体的端口类型和地址类型

三种给socket赋值地址的方法

inet_aton(server_addr_string,&myaddr.sin_addr);
myaddr.sin_addr.s_addr = inet_addr("132.241.5.10");
INADDR_ANY转不转NBO随便
myaddr.sin_addr.s_addr = htons(INADDR_ANY);  
myaddr.sin_addr.s_addr = INADDR_ANY;

两种给socket 赋值端口的方法

#define MYPORT 3490 
myaddr.sin_port = htons(MYPORT);
0(随机端口)转不转NBO随便
myaddr.sin_port = htons(0);
myaddr.sin_port = 0;  

htons/l和ntohs/l等数字转换都不能用于地址转换,因为地址都是点数格式,所以地址只能采用数字/字符串转换如inet_aton,inet_ntoa;
唯一可以用于地址转换的htons是针对INADDR_ANY
 cliaddr.sin_addr.s_addr = htons(INADDR_ANY)

inet_addr()与inet_aton()的区别

  • inet_addr()    是返回值型
struct sockaddr_in ina;

ina.sin_addr.s_addr = inet_addr("132.241.5.10"); 

  • inet_aton()     是参数指针型
struct sockaddr_in ina;

inet_aton("132.241.5.10",&ina.sin_addr);

inet_ntoa  将NBO地址转化成字符串点数格式
参数:结构体变量.sinaddr
返回值:字符串指针

a1 = inet_ntoa(ina.sin_addr);
printf("address 1: %s\n",a1); 
address 1: 132.241.5.10 

inet_addr()的缺陷:必须对-1做检测处理
因为inet_addr()的结果是整型,而发生错误时返回-1。
而 ina.sin_addr.s_addr是unsigned long型
-1在long short显示成111111111,和IP地址255.255.255.255相符合!会被误认为广播地址!

socket编程——sockaddr_in结构体操作的更多相关文章

  1. Linux C Socket编程发送结构体、文件详解及实例

    利用Socket发送文件.结构体.数字等,是在Socket编程中经常需要用到的.由于Socket只能发送字符串,所以可以使用发送字符串的方式发送文件.结构体.数字等等. 本文:http://www.c ...

  2. socket编程 ------ sockaddr_in 和 sockaddr 的区别

    struct sockaddr 和 struct sockaddr_in 这两个结构体用来处理网络通信的地址. // 以下是 IPv4 的定义 struct sockaddr { unsigned s ...

  3. java socket传送一个结构体给用C++编写的服务器解析的问题

    另一端是Java写客户端程序,两者之间需要通信.c++/c接收和发送的都是结构体,而Java是直接发送的字节流或者byte 数组.解决方法:c++/c socket 在发送结构体的时候其实发送的也是字 ...

  4. (转)关于linux中内核编程中结构体的赋值操作(结构体指定初始化)

    网址:http://blog.chinaunix.net/uid-24807808-id-3219820.html 在看linux源码的时候,经常会看到类似于下面的结构体赋值的代码: struct d ...

  5. sockaddr与sockaddr_in结构体简介

    struct sockaddr { unsigned  short  sa_family;     /* address family, AF_xxx */char  sa_data[14];     ...

  6. Golang的面向对象编程【结构体、方法、继承、接口】

    Golang也支持面向对象编程.但与以前学过传统的面向对象编程语言有区别.1)Golang没有类class,Go语言的结构体struct和类class有相似的特性.2)Golang中不存在继承,方法重 ...

  7. 『Python CoolBook』C扩展库_其四_结构体操作与Capsule

    点击进入项目 一.Python生成C语言结构体 C语言中的结构体传给Python时会被封装为胶囊(Capsule), 我们想要一个如下结构体进行运算,则需要Python传入x.y两个浮点数, type ...

  8. C语言--- 字符串数组 、 预处理器和预处理指令 、 多文件编程 、 结构体

    1 输入一个姓名,判断是否是五虎上将. 1.1 问题 本案例需要使用交互的方式判断:用户从控制台输入一个名字,由程序判断该名字是否在五虎上将的名单中.五虎上将的名单是:GuanYu.ZhangFei. ...

  9. 结构体addrinfo, sockaddr, sockaddr_in的区别

    struct sockaddr和struct sockaddr_in这两个结构体用来处理网络通信的地址. 一.sockaddr sockaddr在头文件#include <sys/socket. ...

随机推荐

  1. 如何使用火狐下的两款接口测试工具RESTClient和HttpRequester发送post请求

    Chrome下有著名的Postman,那火狐也有它的左膀右臂,那就是RESTClient和HttpRequester.这两款工具都是火狐的插件,主要用来模拟发送HTTP请求,HTTP请求最常用的两种方 ...

  2. Linux内核分析2

    周子轩原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 本次实验是通过分析一个简单 ...

  3. linux(二) 基本使用命令

    一.常用命令归纳分类 课外网站  http://man.linuxde.net/               http://www.jb51.net/linux/               http ...

  4. 一个优质的Vue组件库应该遵循什么样的设计原则

    一.组件库的价值 就个人而言,拥有一套自己的组件库,可以让你的开发变得更高效,让你在行业里更有价值. 就团队而言,拥有一套团队的组件库,可以让协同开发变得更高效规范,让你的团队在公司更具有影响力. 就 ...

  5. vue2.0 安装及项目搭建(一)

    基本环境安装 1.安装node:从node.js官网下载并安装node.测试:win+R(打开命令行)-------输入cmd-------敲入node -v.如果出现相应版本号,即安装成功: 2.测 ...

  6. Codeforces Round #408 (Div. 2) A B C 模拟 模拟 set

    A. Buying A House time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  7. Google protocol buffer的配置和使用(Linux&&Windows)

    最近自己的服务器做到序列化这一步了,在网上看了下,序列化的工具有boost 和google的protocol buffer, protocol buffer的效率和使用程度更高效一些,就自己琢磨下把他 ...

  8. php网摘收藏

    1.thinkphp3.2.3开发手册: http://document.thinkphp.cn/manual_3_2.html 2.ThinkPHP3.2.3的函数汇总:http://www.thi ...

  9. C++ string类析构报错

    我项目中用到了字符串的Base64转码.DES解密等功能,可能DES解密算法只能解密8字节倍数长度的字符串,所以我得到的结果总会存在一个多余的“尾巴”,于是我想要做一个字符串尾部清理的工作.我的做法是 ...

  10. Gogent相关问题的解决(不断更新)

    1:今天早上打开推特,发现进不去了,google浏览器一直提示404……找不到网址,真心郁闷.后来,查了查,才知道,最近google在北京的主干服务器被xx了,某些省就上不了了…… ……乱七八糟的不说 ...