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. Sort Integers II

    Given an integer array, sort it in ascending order. Use quick sort, merge sort, heap sort or any O(n ...

  2. SQL注入9种绕过WAF方法

    SQL注入9种绕过WAF方法 0x01前言 WAF区别于常规 防火墙 是因为WAF能够过滤特定Web应用程序的内容,而常规防火墙则充当服务器之间的防御门.通过检查HTTP的流量,它可以防御Web应用安 ...

  3. bzoj3007: 拯救小云公主(二分+并查集)

    挺水的题...好多题解说是对偶图,其实感觉不能算严格意义上的对偶图吧QAQ 先二分答案r,然后以boss为中心半径为r的圆不能走,求能否从左下走到右上. 不能从左下走到右上,说明这堆圆把图隔开了,于是 ...

  4. mysql数据库----python操作mysql ------pymysql和SQLAchemy

    本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy 一.pymysql pymsql是Python中操作MySQL的模块,其使用方法和MySQ ...

  5. BFC 块级元素格式化上下文

    Block Formatting Contexts: 块级元素格式化上下文块级元素如何对它的内容(子元素:也是一个块元素)进行布局,以及与其它元素(与内容同级别)的关系和相互作用 普通文档流的布局规则 ...

  6. 解决问题Can’t connect to local MySQL server through socket

    不幸遇到MySQL出现ERROR 2002 (HY000): Can’t connect to local mysql server through socket ‘/tmp/mysql.sock’错 ...

  7. ASP.NET站点Web部署(一键发布的实现)

    在开发过程中经常需要发布到开发环境.测试环境或者预发布环境上给其他同事进行测试验证效果等等,每次发布都要备份,拷贝,修改配置文件等等重复操作非常的麻烦,效率大打折扣,而web部署提供了这样的解决方案: ...

  8. 【BZOJ】3771: Triple FTT+生成函数

    [题意]给定n个物品,价值为$a_i$,物品价格互不相同,求选一个或两个或三个的价值为x的方案数,输出所有存在的x和对应方案数.$ai<=40000$. [算法]生成函数+FFT [题解]要求价 ...

  9. 【CodeForces】679 A. Bear and Prime 100

    [题目]A. Bear and Prime 100 [题意]有一数字x,每次可询问一个数字y是否x的因子,最后输出数字x是否素数,要求询问次数<=20. [题解]容易发现[2,100]范围内的非 ...

  10. iOS程序启动原理---iOS-Apple苹果官方文档翻译

    本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址 //转载请注明出处--本文永久链接:http://www.cnblogs.com/Ch ...