重要的套接字函数

本文详细介绍了套接字函数在客户端和服务器中的使用,包括`socket`函数用于创建套接字,`sockaddr`结构体用于存储地址信息,以及`connect`、`bind`、`listen`和`accept`等函数在客户端和服务器端的角色。文章通过电话类比解释了套接字的工作原理,并给出了客户端和服务器端的简单示例代码。强调了字节序在跨平台通信中的重要性,以及如何使用`htons`和`htonl`等函数处理字节序问题。
摘要由CSDN通过智能技术生成
导读:
   7.5 重要的套接字函数
  FreeBSD提供了与套接字相关的不同函数, “打开”一个套接字我们只 需要四个函数。 有时我们只需要两个。
   7.5.1 客户端-服务器差异
  典型情况中,以套接字为基础的数据通信一端是一个 服务器,另一端是一个 客户端
   7.5.1.1 通用元素
   7.5.1.1.1 socket
  这一个函数在客户端和服务器都要使用:socket(2)。它是这样被声明的:
  int socket(int domain, int type, int protocol);
  
  返回值的类型与open的相同,一个整数。 FreeBSD从和文件句柄相同的池中分配它的值。这就是允许套接字被以对文件相同的方式处理的原因。
  参数domain告诉系统你需要使用什么 协议族。有许多种协议族存在,有些是某些厂商专有的,其它的都非常通用。协议族的声明在 sys/socket.h中
  使用PF_INET是对于 UDP, TCP和其它网间协议(IPv4)的情况。
  对于参数type有五个定义好的值,也在 sys/socket.h中。这些值都以 “SOCK_”开头。 其中最通用的是SOCK_STREAM, 它告诉系统你正需要一个 可靠的流传送服务(和PF_INET一起使用时是指 TCP)。
  如果指定SOCK_DGRAM, 你是在请求 无连接报文传送服务(在我们的情形中是UDP)。
  如何你需要处理基层协议 (例如IP),或者甚至是网络接口 (例如,以太网),你就需要指定 SOCK_RAW。
  最后,参数protocol取决于前两个参数,并非总是有意义。在以上情形中,使用取值0。
   未连接的套接字:对于函数socket我们还没有指定我们要连往什么其它(主机)系统。 我们新建的套接字还是 未连接的
  这是有意的:拿电话类比,我们刚把调制解调器接在电话线上。我们既没有告诉调制解调器发起一个呼叫,也不会应答电话振铃。
   7.5.1.1.2 sockaddr
  各种各样的套接字函数需要指定地址,那是一小块内存空间 (用C语言术语是指向一小块内存空间的指针)。在 sys/socket.h中有各种各样如 struct sockaddr的声明。 这个结构是这样被声明的:
  /*
  * 内核用来存储大多数种类地址的结构
  */
  struct sockaddr {
  unsigned char sa_len; /* 总长度 */
  sa_family_t sa_family; /* 地址族 */
  char sa_data[14]; /* 地址值,实际可能更长 */
  };
  #define SOCK_MAXADDRLEN 255 /* 可能的最长的地址长度 */
  
  注意对于sa_data域的定义有些 不确定性。 那只是被定义为14字节的数组, 注释暗示内容可能超过14字节
  这种不确定性是经过深思熟虑的。套接字是个非常强大的接口。多数人可能认为比Internet接口强不到哪里 ──大多数应用现在很可能都用它 ──套接字可被用于几乎 任何种类的进程间通信, Internet(更精确的说是IP)只是其中的一种。
  sys/socket.h提到的各种类型的协议 将被按照 地址族对待,并把它们就列在 sockaddr定义的前面:
  /*
  * 地址族
  */
  #define AF_UNSPEC 0 /* 未指定 */
  #define AF_LOCAL 1 /* 本机 (管道,portal) */
  #define AF_UNIX AF_LOCAL /* 为了向前兼容 */
  #define AF_INET 2 /* 网间协议: UDP, TCP, 等等 */
  #define AF_IMPLINK 3 /* arpanet imp 地址 */
  #define AF_PUP 4 /* pup 协议: 例如BSP */
  #define AF_CHAOS 5 /* MIT CHAOS 协议 */
  #define AF_NS 6 /* 施乐(XEROX) NS 协议 */
  #define AF_ISO 7 /* ISO 协议 */
  #define AF_OSI AF_ISO
  #define AF_ECMA 8 /* 欧洲计算机制造商协会 */
  #define AF_DATAKIT 9 /* datakit 协议 */
  #define AF_CCITT 10 /* CCITT 协议, X.25 等 */
  #define AF_SNA 11 /* IBM SNA */
  #define AF_DECnet 12 /* DECnet */
  #define AF_DLI 13 /* DEC 直接数据链路接口 */
  #define AF_LAT 14 /* LAT */
  #define AF_HYLINK 15 /* NSC Hyperchannel */
  #define AF_APPLETALK 16 /* Apple Talk */
  #define AF_ROUTE 17 /* 内部路由协议 */
  #define AF_LINK 18 /* 协路层接口 */
  #define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
  #define AF_COIP 20 /* 面向连接的IP, 又名 ST II */
  #define AF_CNT 21 /* Computer Network Technology */
  #define pseudo_AF_RTIP 22 /* 用于识别RTIP包 */
  #define AF_IPX 23 /* Novell 网间协议 */
  #define AF_SIP 24 /* Simple 网间协议 */
  #define pseudo_AF_PIP 25 /* 用于识别PIP包 */
  #define AF_ISDN 26 /* 综合业务数字网(Integrated Services Digital Network) */
  #define AF_E164 AF_ISDN /* CCITT E.164 推荐 */
  #define pseudo_AF_KEY 27 /* 内部密钥管理功能 */
  #define AF_INET6 28 /* IPv6 */
  #define AF_NATM 29 /* 本征ATM访问 */
  #define AF_ATM 30 /* ATM */
  #define pseudo_AF_HDRCMPLT 31 /* 由BPF使用,就不必在接口输出例程
  * 中重写头文件了
  */
  #define AF_NETGRAPH 32 /* Netgraph 套接字 */
  #define AF_SLOW 33 /* 802.3ad 慢速协议 */
  #define AF_SCLUSTER 34 /* Sitara 集群协议 */
  #define AF_ARP 35
  #define AF_BLUETOOTH 36 /* 蓝牙套接字 */
  #define AF_MAX 37
  
  用于指定IP的是 AF_INET。这个符号对应着常量 2。
  在sockaddr中的域 sa_family指定 地址族, 从而决定预先只确定下大致字节数的 sa_data的实际大小。
  特别是当 地址族是AF_INET时,我们可以使用 struct sockaddr_in,这可在 netinet/in.h中找到,任何需要 sockaddr的地方都以此作为实际替代。
  /*
  * 套接字地址,Internet风格
  */
  struct sockaddr_in {
  u
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值