首页 > 代码库 > BSD socket API

BSD socket API

伯克利套接字Berkeley sockets),也称为BSD Socket。伯克利套接字的应用编程接口(API)是采用C语言的进程间通信的库,经常用在计算机网络间的通信。 BSD Socket的应用编程接口已经是网络套接字的抽象标准。大多数其他程序语言使用一种相似的编程接口。它最初是由加州伯克利大学为Unix系统开发出来的。所有现代的操作系统都实现了伯克利套接字接口,因为它已经是连接互联网的标准接口了。



 API函数

这些是伯克利套接字提供的库函数。

  • socket() 创造某种类型的套接字,分配一些系统资源,用返回的整数识别。
  • bind() 一般是用在服务器这边,和一个套接字地址结构相连,比如说是一个特定的本地端口号和一个IP地址。
  • listen()用在服务器一边,导致一个绑定的TCP套接字进入监听状态。
  • connect() 用在客户机这边,给套接字分配一个空闲的端口号。比如说一个TCP套接字,它会试图建立一个新的TCP连接。
  • accept() 用在服务器这边。从客户机那接受请求试图创造一个新的TCP连接,并把一个套接字和这个连接相联系起来。
  • send() and recv(), or write() and read(), or sendto() and recvfrom()用来接收和发送数据。
  • close() 关闭连接,系统释放资源。
  • gethostbyname() and gethostbyaddr()用来解析主机名和地址。
  • select() is used to prune a provided list of sockets for those that are ready to read, ready to write, or that have errors.
  • poll() is used to check on the state of a socket in a set of sockets. The set can be tested to see if any socket can be written to, read from or if an error occurred.
  • getsockopt() is used to retrieve the current value of a particular socket option for the specified socket.
  • setsockopt() is used to set a particular socket option for the specified socket.

更多的细节在下面。

socket()

socket() 为通信创造一个端点并返回一个文件描述符。 socket() 由三个参数:

  • domain, 确定协议族。例如:
    • PF_INET 是IPv4 或者
    • PF_INET6 是 IPv6.
    • PF_UNIX 是本地(用一个文件).
  • type, 是下面中的一个:
    • SOCK_STREAM (可靠的面向连接的服务或者 Stream Sockets)
    • SOCK_DGRAM (数据包服务或者 Datagram Sockets)
    • SOCK_SEQPACKET (可靠的有序的分组服务),或者
    • SOCK_RAW (网络层的原始协议)。
  • protocol 确定实际使用的运输层。最常见的是 IPPROTO_TCPIPPROTO_SCTPIPPROTO_UDPIPPROTO_DCCP。这些协议是在<netinet/in.h>中定义的。如果 domain 和 type已经确定,“0” 可以用来选择一个默认的协议。

如果出错返回-1,否则返回一个代表文件描述符的整数。

函数原型
int socket(int domain, int type, int protocol);

bind()

bind() 给套接字分配一个地址。当使用 socket()创造一个套接字时, 只是给定了协议族,并没有分配地址。在套接字能够接受来自其他主机的连接前,必须用bind()给它绑定一个地址。 bind() 由三个参数:

  • sockfd, 代表socket的文件描述符。
  • my_addr, 指向 sockaddr 结构体的指针,代表要绑定的地址 。
  • addrlen, 是sockaddr结构体的大小。

Bind()返回0表示成功,错误返回-1。

函数原型
int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);

 listen()

一旦一个套接字和一个地址联系之后,listen() 监听到来的连接。但是这只适用于对面向连接的模式,例如 套接字类型是 (SOCK_STREAMSOCK_SEQPACKET)。listen()需要两个参数:

  • sockfd,一个有效的套接字描述符。
  • backlog,一个整数,表示一次能够等待的最大连接数目。操作系统通常会对这个值设置上限。

一旦连接被接受,返回0表示成功,错误返回-1。

函数原型:
int listen(int sockfd, int backlog);

accept()

当应用程序监听来自其他主机的面对数据流的连接时,通过事件(比如Unix select()系统调用)通知它。必须用accept()函数初始化连接。 Accept() 为每个连接创立新的套接字并从监听队列中移除这个连接。它使用如下参数:

  • sockfd,监听的套接字描述符
  • cliaddr, 指向sockaddr 结构体的指针,客户机地址信息。
  • addrlen,指向 socklen_t的指针,确定客户机地址结构体的大小 。

返回新的套接字描述符,出错返回-1。进一步的通信必须通过这个套接字。

Datagram 套接字不要求用accept()处理,因为接收方可能用监听套接字立即处理这个请求。

函数原型:
int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);

connect()

connect()系统调用为一个套接字设置连接,参数有文件描述符和主机地址。

某些类型的套接字是无连接的,大多数是UDP协议。对于这些套接字,连接时这样的:默认发送和接收数据的主机由给定的地址确定,可以使用 send()和 recv()。 返回-1表示出错,0表示成功。

函数原型:
int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);

gethostbyname() 和 gethostbyaddr()

gethostbyname() 和 gethostbyaddr()函数是用来解析主机名和地址的。可能会使用DNS服务或者本地主机上的其他解析机制(例如查询/etc/hosts)。返回一个指向 struct hostent的指针,这个结构体描述一个IP主机。函数使用如下参数:

  • name 指定主机名。例如 www.wikipedia.org
  • addr 指向 struct in_addr的指针,包含主机的地址。
  • len 给出 addr的长度,以字节为单位。
  • type 指定地址族类型 (比如 AF_INET)。

出错返回NULL指针,可以通过检查 h_errno 来确定是临时错误还是未知主机。正确则返回一个有效的 struct hostent *

这些函数并不是伯克利套接字严格的组成部分。这些函数可能是过时了,新函数是 getaddrinfo() and getnameinfo(), 这些新函数是基于addrinfo数据结构。

函数原型:
struct hostent *gethostbyname(const char *name);
struct hostent *gethostbyaddr(const void *addr, int len, int type);

协议和地址

套接字API是Unix网络的通用接口,允许使用各种网络协议和地址。

下面列出了一些例子,在现在的 Linux 和BSD中一般都已经实现了。

PF_LOCAL, PF_UNIX, PF_FILE
                Local to host (pipes and file-domain)
PF_INET         IP protocol family
PF_AX25         Amateur Radio AX.25
PF_IPX          Novell Internet Protocol
PF_APPLETALK    Appletalk DDP
PF_NETROM       Amateur radio NetROM
PF_BRIDGE       Multiprotocol bridge
PF_ATMPVC       ATM PVCs
PF_X25          Reserved for X.25 project
PF_INET6        IP version 6
PF_ROSE         Amateur Radio X.25 PLP
PF_DECnet       Reserved for DECnet project
PF_NETBEUI      Reserved for 802.2LLC project
PF_SECURITY     Security callback pseudo AF
PF_KEY          PF_KEY key management API
PF_NETLINK, PF_ROUTE
                routing API
PF_PACKET       Packet family
PF_ASH          Ash
PF_ECONET       Acorn Econet
PF_ATMSVC       ATM SVCs
PF_SNA          Linux SNA Project
PF_IRDA         IRDA sockets
PF_PPPOX        PPPoX sockets
PF_WANPIPE      Wanpipe API sockets
PF_BLUETOOTH    Bluetooth sockets

BSD socket API