1.套接字是通信端点的抽象。
与应用程序要用文件描述符访问文件一样,访问套接字也需要用套接字描述符。套接字描述符在UNIX系统是用文件描述符实现的。
要创建一个套接字,可以调用socket函数。
#include<sys/socket.h>
int socket(int domain,int type,int protocol);//返回值:成功返回文件(套接字)描述符,出错返回-1。
a)参数domain确定通信的特性,包括地址格式。(AF_INET,AF_INET6,AF_UNIX,AF_UNSPEC等)
b)参数type确定套接字的类型,进一步确定通信特征。
SOCK_DGRAM 长度固定的、无连接的不可靠报文传递
SOCK_RAW IP 协议的数据报接口
SOCK_SEQPACKET 长度固定、有序、可靠的面向连接报文传递
SOCK_STREAM 有序、可靠、双向的面向连接字节流
c)参数protocol通常是零,表示按给定的域和套接字类型选择默认协议。
2.shutdown禁止套接字上得输入/输出
#include<sys/socket.h>
int shutdown(int sockfd,int how); //返回值:成功返回0,出错返回-1。
a)如果how是SHUT_RD,那么无法从套接字读取数据;
b)如果how是SHUT_WR,那么无法从套接字发送数据;
c)如果how是SHUT_RDWR,则将同时无法读取和发送数据。
3.将套接字与地址绑定
1)用bind函数将地址绑定到一个套接字。
#include<sys/socket.h>
int bind(int sockfd,const struct sockaddr *addr,socklen_t len); //成功返回0,出错返回-1。
2)调用函数getsockname来发现绑定到一个套接字的地址
int getsockname(int sockfd,struct sockaddr *restrict addr,socklen_t *restrict alenp); //成功返回0,出错返回-1。
alenp为一个指向整数的指针,该整数指定缓存区sockaddr的大小。返回时,该整数会被设置成返回地址的大小。如果该地址和提供的缓冲区长度不匹配,则将其截断而不报错。如果当前没有绑定到该套接字的地址,其结果没有定义。
3)如果套接字已经和对方连接,调用getpeername来找到对方的地址
#include<sys/socket.h>
int getpeername(int sockfd,struct sockaddr *restrict addr,socklen_t *restrict alenp); //成功返回0,出错返回-1。
除了还会返回对方的地址之外,函数getpeername和getsockname一样。
4.建立连接
#include<sys/socket.h>
int connect(int sockfd,const struct sockaddr *addr,socklen_t len); //成功返回0,失败返回-1。
服务器调用listen来宣告可以接受连接请求。
#include<sys/socket.h>
int listen(int sockfd,int backlog); //成功返回0,失败返回-1。
参数backlog提供了一个提示,用于表示该进程所要入队的连接请求数量。其实际值由系统决定,但上限由<sys/socket.h>中SOMAXCONN指定。
一旦服务器调用了listen,套接字就能接收连接请求。使用函数accept获得连接请求并建立连接。
#include<sys/socket.h>
int accept(int sockfd,struct sockaddr *restrict addr,socklen_t *restrict len); //成功返回文件(套接字)描述符,出错返回-1。
函数accept所返回的文件描述符是套接字描述符,该描述符连接到调用connect的客户端。
如果不关心客户端标识,可以将参数addr和len设为NULL;否则,在调用accept之前,应将参数addr设为足够大的缓冲区来存放地址,并将len指向代表这个缓冲区大小的整数的指针。返回时,accept会在缓冲区填充客户端的地址并且更新指针len所指向的整数为该地址的大小。
如果没有连接请求等待处理,accept会阻塞知道一个请求到来。如果sockfd处于非阻塞模式,accept会返回-1并将errno设置为EAGAIN或EWOULDBLOCK。
如果服务器调用accept并且当前没有连接请求,服务器会阻塞知道一个请求都来。另外,服务器可以使用poll或select来等待一个请求的到来。在这种情况下,一个等待处理的连接请求套接字会以可读的方式出现。