1
xufang 2015-12-28 20:33:32 +08:00
呃, socket 光看博客是看不会哒,从 UNP 看起吧。
|
2
LXJ 2015-12-28 20:45:18 +08:00
socket 描述符类似 file descriptor ,并不是 sa_family ;
除 UNP 外,推荐《 TCP/IP Sockets in C, Second Edition 》这本小书,里面有关于 socket 编程一步步的讲解,有可运行的示例代码,也有对示例代码细致的讲解。 |
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 字节. |
6
billlee 2015-12-28 21:13:30 +08:00
1. socket 的 API 来源于 BSD. 在 Unix 下, 一切皆文件, socket 描述符是文件描述符的一种,就是一个整数。
2. socket 有很多类型,不同类型的 socket 的地址结构也是不一样的。你可以理解为 struct sockaddr 是一个抽象类, sa_data 是给子类特有的字段留的空间。 |
7
fyyz OP 谢谢楼上各位的解答。其实看了各位的解答感觉还是有点一知半解,准备买本 UNP 看看。
|
8
shyling 2015-12-28 21:59:33 +08:00
描述符全是数字=。=
|
9
elgoog1970 2015-12-28 22:26:14 +08:00
lz 问的问题,实在让这些码农无法回答,还是先学习下网络,在看看《 unix 网络编程》,并把上面的代码练习下,最后写个简单的 FTP 或者 chat-tool ,那 lz 就对 socket 方面的知识有所了解了:)
|
10
k9982874 2015-12-28 23:55:19 +08:00 via iPad
第一个问题 sock 描述符是一个文件句柄 /描述符, sockaddr 结构是创建 sock 时需要的参数
其他问题 5 楼给了正解 |
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()的返回值,它是一个索引,即一个整形 |