JavaScript is required to for searching.
跳过导航链接
退出打印视图
编程接口指南     Oracle Solaris 10 1/13 Information Library (简体中文)
search filter icon
search icon

文档信息

前言

1.  内存和 CPU 管理

2.  用于 Solaris Cluster 的远程共享内存 API

3.  会话描述协议 API

4.  进程调度程序

5.  地址组 API

6.  输入/输出接口

7.  进程间通信

8.  套接字接口

SunOS 4 二进制兼容性

套接字概述

套接字库

套接字类型

接口组

套接字基础知识

创建套接字

绑定本地名称

建立连接

连接错误

数据传输

关闭套接字

连接流套接字

输入/输出多路复用

数据报套接字

标准例程

主机和服务名称

主机名-hostent

网络名称-netent

协议名-protoent

服务名-servent

其他例程

客户机/服务器程序

套接字和服务器

套接字和客户机

无连接服务器

高级套接字主题

带外数据

非阻塞套接字

异步套接字 I/O

中断驱动套接字 I/O

信号和进程组 ID

选择特定的协议

地址绑定

套接字选项

inetd 守护进程

广播及确定网络配置

使用多播

发送 IPv4 多播数据报

接收 IPv4 多播数据报

发送 IPv6 多播数据报

接收 IPv6 多播数据报

流控制传输协议

SCTP 栈实现

SCTP 套接字接口

sctp_bindx()

sctp_opt_info()

sctp_recvmsg()

sctp_sendmsg()

sctp_send()

分叉关联

sctp_getpaddrs()

sctp_freepaddrs()

sctp_getladdrs()

sctp_freeladdrs()

SCTP 用法代码示例

9.  使用 XTI 和 TLI 编程

10.  包过滤钩子

11.  传输选择和名称到地址映射

12.  实时编程和管理

13.  Solaris ABI 和 ABI 工具

A.  UNIX 域套接字

索引

标准例程

本节介绍可以用来查找和构造网络地址的例程。除非另行说明,否则本节中介绍的接口只适用于 Internet 系列。

在客户机与服务器通信之前,在远程主机上查找服务需要许多级别的映射。为了便于用户使用,每个服务都具有一个名称。服务名和主机名必须转换为网络地址。最后,网络地址必须可用于查找并路由到主机。网络体系结构之间的具体映射情况可以不同。

标准例程将主机名映射到网络地址,将网络名映射到网络号,将协议名映射到协议号,将服务名映射到端口号。此外,标准例程还指明与服务器进程通信时所使用的相应协议。使用其中任一例程时,必须包括文件 netdb.h

主机和服务名称

接口 getaddrinfo(3SOCKET)getnameinfo(3SOCKET)gai_strerror(3SOCKET)freeaddrinfo(3SOCKET) 提供了一种在主机上的服务名称与地址之间进行转换的简化方法。这些接口比 getipnodebyname(3SOCKET)gethostbyname(3NSL)getservbyname(3SOCKET) API 更新。将透明地处理 IPv6 和 IPv4 地址。

getaddrinfo(3SOCKET) 例程返回指定主机名和服务名的组合地址和端口号。由于会动态分配 getaddrinfo(3SOCKET) 所返回的信息,因此必须通过 freeaddrinfo(3SOCKET) 释放信息以防止内存泄漏。getnameinfo(3SOCKET) 返回与指定地址和端口号关联的主机名和服务名。调用 gai_strerror(3SOCKET) 以便基于 getaddrinfo(3SOCKET)getnameinfo(3SOCKET) 所返回的 EAI_xxx 代码显示错误消息。

以下是使用 getaddrinfo(3SOCKET) 的示例。

struct addrinfo        *res, *aip;
struct addrinfo        hints;
int                    error;

/* Get host address.  Any type of address will do. */
bzero(&hints, sizeof (hints));
hints.ai_flags = AI_ALL|AI_ADDRCONFIG;
hints.ai_socktype = SOCK_STREAM;

error = getaddrinfo(hostname, servicename, &hints, &res);
if (error != 0) {
    (void) fprintf(stderr, "getaddrinfo: %s for host %s service %s\n",
    gai_strerror(error), hostname, servicename);
    return (-1);
}

res 指向的结构中处理完 getaddrinfo(3SOCKET) 所返回的信息之后,应该通过 freeaddrinfo(res) 释放存储空间。

getnameinfo(3SOCKET) 例程在确定错误原因时特别有用,如以下示例所示:

struct sockaddr_storage faddr;
int                     sock, new_sock, sock_opt;
socklen_t               faddrlen;
int                     error;
char                    hname[NI_MAXHOST];
char                    sname[NI_MAXSERV];
...
faddrlen = sizeof (faddr);
new_sock = accept(sock, (struct sockaddr *)&faddr, &faddrlen);
if (new_sock == -1) {
    if (errno != EINTR && errno != ECONNABORTED) {
        perror("accept");
    }
    continue;
}
error = getnameinfo((struct sockaddr *)&faddr, faddrlen, hname, 
    sizeof (hname), sname, sizeof (sname), 0);
if (error) {
    (void) fprintf(stderr, "getnameinfo: %s\n",
        gai_strerror(error));
} else {
    (void) printf("Connection from %s/%s\n", hname, sname);
}

主机名-hostent

Internet 主机名到地址映射由 hostent 结构表示,如 gethostent(3NSL) 中所定义:

struct hostent {
    char  *h_name;            /* official name of host */
    char  **h_aliases;        /* alias list */
    int   h_addrtype;         /* hostaddrtype(e.g.,AF_INET6) */
    int   h_length;           /* length of address */
    char  **h_addr_list;      /* list of addrs, null terminated */
};
/*1st addr, net byte order*/
#define h_addr h_addr_list[0]
getipnodebyname(3SOCKET)

将 Internet 主机名映射到 hostent 结构

getipnodebyaddr(3SOCKET)

将 Internet 主机地址映射到 hostent 结构

freehostent(3SOCKET)

释放 hostent 结构的内存

inet_ntop(3SOCKET)

将 Internet 主机地址映射到字符串

这些例程返回的 hostent 结构中包含主机名、主机别名、地址类型,以及以 NULL 结尾的长度可变地址的列表。此地址列表是必需的,因为主机可以具有许多地址。h_addr 定义用于向后兼容,并且是 hostent 结构的地址列表中的第一个地址。

网络名称-netent

用于将网络名映射到网络号以及将网络号映射到网络名的例程将返回 netent 结构:

/*
 * Assumes that a network number fits in 32 bits.
 */
struct netent {
   char     *n_name;      /* official name of net */
   char     **n_aliases;  /* alias list */
   int      n_addrtype;   /* net address type */
   int      n_net;        /* net number, host byte order */
};

getnetbyname(3SOCKET)getnetbyaddr_r(3SOCKET)getnetent(3SOCKET) 是前面介绍的主机例程的网络对应项。

协议名-protoent

protoent 结构定义用于 getprotobyname(3SOCKET)getprotobynumber(3SOCKET)getprotoent(3SOCKET) 且在 getprotoent(3SOCKET) 中定义的协议到名称映射:

struct protoent {
    char    *p_name;       /* official protocol name */
    char    **p_aliases    /* alias list */
    int     p_proto;       /* protocol number */
};

服务名-servent

Internet 系列服务驻留在特定的已知端口,并使用特定的协议。getprotoent(3SOCKET) 中定义的 servent 结构描述了服务名到端口号映射:

struct servent {
    char    *s_name;        /* official service name */
    char    **s_aliases;    /* alias list */
    int     s_port;         /* port number, network byte order */
    char    *s_proto;       /* protocol to use */
};

getservbyname(3SOCKET) 将服务名以及限定协议(可选)映射到 servent 结构。调用:

sp = getservbyname("telnet", (char *) 0);

将返回使用任意协议的 telnet 服务器的服务规范。调用:

sp = getservbyname("telnet", "tcp");

将返回使用 TCP 协议的 telnet 服务器。还提供了 getservbyport(3SOCKET)getservent(3SOCKET)getservbyport(3SOCKET) 具有的接口类似于 getservbyname(3SOCKET) 使用的接口。可以指定一个可选协议名来限定查找。

其他例程

可以使用其他一些例程来简化名称和地址的处理。下表概述了用于处理长度可变字节字符串以及字节交换网络地址和值的例程。

表 8-2 运行时库例程

接口
用法概要
比较字节字符串;如果相同,则为 0,否则不为 0
n 个字节从 s2 复制到 s1
n 个字节设置为以 base 开始的 value
从主机字节顺序转换到网络字节顺序的 32 位值
从主机字节顺序转换到网络字节顺序的 16 位值
从网络字节顺序转换到主机字节顺序的 32 位值
从网络字节顺序转换到主机字节顺序的 16 位值

因为操作系统希望以网络顺序提供地址,所以提供了字节交换例程。在某些体系结构中,主机字节顺序不同于网络字节顺序,因此有时程序必须对值进行字节交换。返回网络地址的例程以网络顺序执行此操作。仅在解释网络地址时会出现字节交换问题。例如,以下代码设置 TCP 或 UDP 端口的格式:

printf("port number %d\n", ntohs(sp->s_port));

在不需要这些例程的计算机上,将这些例程定义为空宏。