struct sockaddr 这个结构体是linux的网络编程接口中用来表示IP地址的标准结构体,bind、connect等函数中都需要这个结构体,这个结构体是兼容IPV4和IPV6的。

在实际编程中这个结构体会被一个struct sockaddr_in所填充。

sockaddr

用于存储参与(IP)Windows套接字通信的计算机上的一个internet协议(IP)地址。为了统一地址结构的表示方法 ,统一接口函数,使得不同的地址结构可以被bind()、connect()、recvfrom()、sendto()等函数调用。但一般的编程中并不直接对此数据结构进行操作,而使用另一个与之等价的数据结构sockaddr_in。这是由于Microsoft TCP/IP套接字开发人员的工具箱仅支持internet地址字段,而实际填充字段的每一部分则遵循sockaddr_in数据结构,两者大小都是16字节,所以二者之间可以进行切换。

sockaddr 在bind的man手册中提到

struct sockaddr
{
sa_family_t sa_family; //所选协议族AF_INET
char sa_data[14]; //ip地址及端口号
}
说明:
sa_family :是2字节的地址家族,一般都是“AF_xxx”的形式,它的值包括三种:AF_INET,AF_INET6和AF_UNSPEC。
如果指定AF_INET,那么函数就不能返回任何IPV6相关的地址信息;如果仅指定了AF_INET6,则就不能返回任何IPV4地址信息。
AF_UNSPEC则意味着函数返回的是适用于指定主机名和服务名且适合任何协议族的地址。如果某个主机既有AAAA记录(IPV6)地址,同时又有A记录(IPV4)地址,那么AAAA记录将作为sockaddr_in6结构返回,而A记录则作为sockaddr_in结构返回
通常用的都是AF_INET。
 

sockaddr_in

struct sockaddr_in {
  short int sin_family; /* Address family */
  unsigned short int sin_port; /* Port number */
  struct in_addr sin_addr; /* Internet address */
  unsigned char sin_zero[8]; /* Same size as struct sockaddr */
  };
  sin_family:指代协议族,在socket编程中只能是AF_INET
  sin_port:存储端口号(使用网络字节顺序)
  sin_addr:存储IP地址,使用in_addr这个数据结构
  sin_zero:是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。
而其中in_addr结构的定义如下:
typedef struct in_addr {
  union {
  struct{ unsigned char s_b1,s_b2, s_b3,s_b4;} S_un_b;
  struct{ unsigned short s_w1, s_w2;} S_un_w;
  unsigned long S_addr;
  } S_un;
  } IN_ADDR;
阐述下in_addr的含义,很显然它是一个存储ip地址的共用体有三种表达方式:
第一种用四个字节来表示IP地址的四个数字;
第二种用两个双字节来表示IP地址;
第三种用一个长整型来表示IP地址。
给in_addr赋值的一种最简单方法是使用inet_addr函数,它可以把一个代表IP地址的字符串赋值转换为in_addr类型,如addrto.sin_addr.s_addr=inet_addr("192.168.0.2");
其反函数是inet_ntoa,可以把一个in_addr类型转换为一个字符串。
 

虽然是两个结构体可是二者的占用的内存是一致的,因此可以互相转化。

sockaddr常用于bind、connect、recvfrom、sendto等函数的参数,指明地址信息。是一种通用的套接字地址。

而sockaddr_in 一般是储存地址和端口的。用于信息的显示及存储使用

例如:

struct sockaddr_in addr_server;

addr_server.sin_family = AF_INET;
addr_server.sin_port = htons(RPORT);
addr_server.sin_addr.s_addr = inet_addr(RHOST);

然而,在类似于bind accept的函数中

ret = bind(fd_sock, (struct sockaddr *)&addr_server, sizeof(addr_server));
if(ret < 0)
{
perror("bind");
return -1;
}

之前只是这样的记下来了,可是知道一天,想显示所连接的客户端的ip地址的时候,就发现了问题所在

char *inet_ntoa(struct in_addr in);

函数原型是这样的,可是在

struct in_addr
{
in_addr_t s_addr;
};

这个in_addr是sockaddr_in的一个mamber

fd_connection = accept(fd_sock,  (struct sockaddr *)&addr_client, &addr_client_len);
if(fd_connection < 0)
{
perror("accept");
return -1;
}
printf("connected! : %d\n", fd_connection);
printf("%s%s\n", "the client ip is :", inet_ntoa(addr_client.sin_addr));

  

网络编程——sockaddr 与 sockaddr_in的更多相关文章

  1. socket 编程--sockaddr与sockaddr_in区别与联系(转)

    在linux环境下,结构体struct sockaddr在/usr/include/linux/socket.h中定义,具体如下:typedef unsigned short sa_family_t; ...

  2. Linux Socket 网络编程

    Linux下的网络编程指的是socket套接字编程,入门比较简单.在学校里学过一些皮毛,平时就是自学玩,没有见识过真正的socket编程大程序,比较遗憾.总感觉每次看的时候都有收获,但是每次看完了之后 ...

  3. Linux网络编程-IO复用技术

    IO复用是Linux中的IO模型之一,IO复用就是进程预先告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程进程处理,从而不会在单个IO上阻塞了.Linux中,提 ...

  4. Windows 网络编程

    网络编程 API ,失败返回 -,错误代码 WSASYSNOTREADY 表示基础网络子系统没有准备好网络通行,WSAVERNOTSUPPORTED 表示 Socket 版本不支持,WSAEINPRO ...

  5. 【深入浅出Linux网络编程】 “实践 -- TCP & UDP”

    通过上一篇博客的学习,你应该对基于epoll的事件触发机制有所掌握,并且通过阅读sio.c/sio.h应该也学会了如何封装epoll以及如何通过设计令epoll更加实用(用户回调,用户参数). 简单回 ...

  6. 【linux草鞋应用编程系列】_5_ Linux网络编程

    一.网络通信简介   第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章.   二.linux网络通信     在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...

  7. python之网络编程

    本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类: 消息传递(管道.FIFO.消息队列) 同步(互斥量.条件变量.读写锁.文件和写记录锁.信号量) 共享内存(匿名的和具名的) 远程过程调用 ...

  8. Socket网络编程-基础篇

    Socket网络编程 网络通讯三要素: IP地址[主机名] 网络中设备的标识 本地回环地址:127.0.0.1 主机名:localhost 端口号 用于标识进程的逻辑地址 有效端口:0~65535 其 ...

  9. UNIX网络编程——getsockname和getpeername函数

    UNIX网络编程--getsockname和getpeername函数   来源:网络转载   http://www.educity.cn/linux/1241293.html     这两个函数或者 ...

随机推荐

  1. js 宏任务和微任务

    .宏任务(macrotask )和微任务(microtask ) macrotask 和 microtask 表示异步任务的两种分类. 在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首 ...

  2. axios浏览器异步请求方法封装 XMLHttpRequest

    axios学习笔记defaults(浏览器端异步请求处理方式) 浏览器异步请求方法封装,主要使用XMLHttpRequest lib/adapters/xhr.js //入口 var utils = ...

  3. vue 复制文本到剪切板上

    1.下载clipboard.js npm install vue-clipboard2 --save 2.引入,可以在mian.js中全局引入也可以在单个vue中引入 import Clipboard ...

  4. [JAVA] 日常填坑 java.lang.SecurityException: Prohibited package name: java.xxx

    java虚拟机不允许包名以java开头. https://blog.csdn.net/sinat_28690417/article/details/72328547

  5. url拼接参数格式

    在一些情况下,需要直接往url上拼接请求参数. http://www.yanggb.com?flag=1&type=normal&role=customer 通过上面的例子就可以看出, ...

  6. SpringMVC-方法四种类型返回值总结,你用过几种?

    SpringMVC 现在算是 Java 领域的一个基础性框架了,很多人天天用,可是对于 SpringMVC 方法的返回值,你又是否完全清楚呢?今天松哥就来和大家聊一聊 SpringMVC 中四种不同类 ...

  7. C# 中 ==和equals的区别

    不想说太多,直接上代码,这两个就没什么联系,有自己独立的规则.联系在一起其实不利于记忆. 下面是测试代码 Console.WriteLine("--equals和==的区别--") ...

  8. 如何写出优雅的 Golang 代码

    原文: https://draveness.me/golang-101.html Go 语言是一门简单.易学的编程语言,对于有编程背景的工程师来说,学习 Go 语言并写出能够运行的代码并不是一件困难的 ...

  9. Python【day 8】文件

    一.文件操作 open(文件路径,mode='模式',encoding='utf-8')模式:r w a rb wb ab r+ w+ a+ r+b w+b a+b常用的:r w ab表示字节,处理费 ...

  10. PHP生成json

    索引数组 <?php //json_encode(数组/对象) $color = array('red','blue','green'); echo json_encode($color); / ...