V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fyyz
V2EX  ›  C

在看 socket,有点困惑

  •  
  •   fyyz · 2015-12-28 20:12:22 +08:00 · 1557 次点击
    这是一个创建于 3013 天前的主题,其中的信息可能已经有所发展或是发生改变。
    http://www.cnblogs.com/L-hq815/archive/2012/07/09/2583043.html
    第四段:结构体


    1 ,“ socket 描述符”是结构体 sockaddr 中的 sa_family 吗?
    2 , sa_data[14]; 这到底是啥玩意?这串数组里存的“ 14 字节协议地址”究竟是什么?
    3 ,文章里面说 struct sockaddr 和 struct sockaddr_in 是并列的,但是我看来都是大小不一样啊。


    实在看不懂,反反复复看了好几遍,希望高人解答。
    11 条回复    2015-12-29 11:43:43 +08:00
    xufang
        1
    xufang  
       2015-12-28 20:33:32 +08:00
    呃, socket 光看博客是看不会哒,从 UNP 看起吧。
    LXJ
        2
    LXJ  
       2015-12-28 20:45:18 +08:00
    socket 描述符类似 file descriptor ,并不是 sa_family ;

    除 UNP 外,推荐《 TCP/IP Sockets in C, Second Edition 》这本小书,里面有关于 socket 编程一步步的讲解,有可运行的示例代码,也有对示例代码细致的讲解。
    fyyz
        3
    fyyz  
    OP
       2015-12-28 20:49:00 +08:00
    @LXJ C++也是一样吗?
    LXJ
        4
    LXJ  
       2015-12-28 21:02:25 +08:00
    @fyyz 应该一样;这里主要还是讲解 Socket 编程,和语言关系不大。
    hitmanx
        5
    hitmanx  
       2015-12-28 21:02:52 +08:00
    2. sa_data[14]; 这到底是啥玩意?这串数组里存的“ 14 字节协议地址”究竟是什么?
    3 ,文章里面说 struct sockaddr 和 struct sockaddr_in 是并列的,但是我看来都是大小不一样啊。


    我已经忘得差不多了=.=,但是看了一下你的那篇文章,感觉是这个意思:

    struct sockaddr {
       unsigned short sa_family; /* 地址家族, AF_xxx */
       char sa_data[14]; /*14 字节协议地址*/
    };

    struct sockaddr_in {
       short int sin_family; /* 通信类型 */
       unsigned short int sin_port; /* 端口 */
       struct in_addr sin_addr; /* Internet 地址 */
       unsigned char sin_zero[8]; /* 与 sockaddr 结构的长度相同*/
    };

    文中的意思是这两个结构体是等效的,可以看到除了共同的 sa_family 以外,上面的 sa_data 为 14 字节,下面的端口(2 字节) + ipv4 的地址(4 字节) + char[8],刚好也是 14 字节.
    billlee
        6
    billlee  
       2015-12-28 21:13:30 +08:00
    1. socket 的 API 来源于 BSD. 在 Unix 下, 一切皆文件, socket 描述符是文件描述符的一种,就是一个整数。
    2. socket 有很多类型,不同类型的 socket 的地址结构也是不一样的。你可以理解为 struct sockaddr 是一个抽象类, sa_data 是给子类特有的字段留的空间。
    fyyz
        7
    fyyz  
    OP
       2015-12-28 21:17:45 +08:00
    谢谢楼上各位的解答。其实看了各位的解答感觉还是有点一知半解,准备买本 UNP 看看。
    shyling
        8
    shyling  
       2015-12-28 21:59:33 +08:00
    描述符全是数字=。=
    elgoog1970
        9
    elgoog1970  
       2015-12-28 22:26:14 +08:00
    lz 问的问题,实在让这些码农无法回答,还是先学习下网络,在看看《 unix 网络编程》,并把上面的代码练习下,最后写个简单的 FTP 或者 chat-tool ,那 lz 就对 socket 方面的知识有所了解了:)
    k9982874
        10
    k9982874  
       2015-12-28 23:55:19 +08:00 via iPad
    第一个问题 sock 描述符是一个文件句柄 /描述符, sockaddr 结构是创建 sock 时需要的参数
    其他问题 5 楼给了正解
    codesun
        11
    codesun  
       2015-12-29 11:43:43 +08:00
    linux 的头文件里解释得挺清楚的:

    旧的声明,为何是 14 ,可以参考‘ talk ’协议
    /* This is the 4.3 BSD `struct sockaddr' format, which is used as wire
    format in the grotty old 4.3 `talk' protocol. */
    struct osockaddr
    {
    unsigned short int sa_family;
    unsigned char sa_data[14];
    };

    如下是新的声明,总体长度不变
    /* Structure describing a generic socket address. */
    struct sockaddr
    {
    __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */
    char sa_data[14]; /* Address data. */
    };

    如下为 ipv4 的 sockaddr ,明确说明需要填充至 sockaddr 的长度
    /* Structure describing an Internet socket address. */
    struct sockaddr_in
    {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port; /* Port number. */
    struct in_addr sin_addr; /* Internet address. */

    /* Pad to size of `struct sockaddr'. */
    unsigned char sin_zero[sizeof (struct sockaddr) -
    __SOCKADDR_COMMON_SIZE -
    sizeof (in_port_t) -
    sizeof (struct in_addr)];
    };
    至于为何提供 sockaddr 和 sockaddr_in ,按照我个人的理解,是因为历史原因,比如‘ talk ’,其次,现在除了上述 2 个 sockaddr ,还有供 ipv6 使用的 sockaddr_in6 ,那么为了保证 API 的向下兼容, sockaddr 反而成了一种抽象表示,但 C 并不提供类似的语法,因此只能使用相对暴力的强制转型了(前提是保证 struct 内部变量的偏移一致),使用的时候只需要根据 sa_family 即可判断到底是 ipv4 还是 ipv6

    另文件描述符即 fd ,就是 socket()的返回值,它是一个索引,即一个整形
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1152 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 23:00 · PVG 07:00 · LAX 16:00 · JFK 19:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.