伯克利套接字(Berkeley sockets),也称为BSD Socket。伯克利套接字的应用编程接口(API)是采用C语言的进程间通信的库,经常用在计算机网络间的通信。 BSD Socket的应用编程接口已经是网络套接字的抽象标准。大多数其他程序语言使用一种相似的编程接口。它最初是由加州伯克利大学为Unix系统开发出来的。所有现代的操作系统都实现了伯克利套接字接口,因为它已经是连接互联网的标准接口了。
这些是伯克利套接字提供的库函数。
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()
由三个参数:
PF_INET
是IPv4 或者PF_INET6
是 IPv6.PF_UNIX
是本地(用一个文件).SOCK_STREAM
(可靠的面向连接的服务或者 Stream Sockets)SOCK_DGRAM
(数据包服务或者 Datagram Sockets)SOCK_SEQPACKET
(可靠的有序的分组服务),或者SOCK_RAW
(网络层的原始协议)。IPPROTO_TCP
, IPPROTO_SCTP
, IPPROTO_UDP
, IPPROTO_DCCP
。这些协议是在<netinet/in.h>中定义的。如果 domain
和 type
已经确定,“0
” 可以用来选择一个默认的协议。如果出错返回-1,否则返回一个代表文件描述符的整数。
int socket(int domain, int type, int protocol);
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()
监听到来的连接。但是这只适用于对面向连接的模式,例如 套接字类型是 (SOCK_STREAM
, SOCK_SEQPACKET
)。listen()需要两个参数:
sockfd
,一个有效的套接字描述符。backlog
,一个整数,表示一次能够等待的最大连接数目。操作系统通常会对这个值设置上限。一旦连接被接受,返回0表示成功,错误返回-1。
int listen(int sockfd, int backlog);
当应用程序监听来自其他主机的面对数据流的连接时,通过事件(比如Unix select()系统调用)通知它。必须用accept()
函数初始化连接。 Accept() 为每个连接创立新的套接字并从监听队列中移除这个连接。它使用如下参数:
sockfd
,监听的套接字描述符cliaddr
, 指向sockaddr 结构体的指针,客户机地址信息。addrlen
,指向 socklen_t
的指针,确定客户机地址结构体的大小 。返回新的套接字描述符,出错返回-1。进一步的通信必须通过这个套接字。
Datagram 套接字不要求用accept()处理,因为接收方可能用监听套接字立即处理这个请求。
int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
connect()
系统调用为一个套接字设置连接,参数有文件描述符和主机地址。
某些类型的套接字是无连接的,大多数是UDP协议。对于这些套接字,连接时这样的:默认发送和接收数据的主机由给定的地址确定,可以使用 send()和 recv()。 返回-1表示出错,0表示成功。
int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
gethostbyname()
和 gethostbyaddr()
函数是用来解析主机名和地址的。可能会使用DNS服务或者本地主机上的其他解析机制(例如查询/etc/hosts)。返回一个指向 struct hostent的指针,这个结构体描述一个IP主机。函数使用如下参数:
出错返回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
原文:http://www.cnblogs.com/god-of-death/p/7152387.html