linux 一切皆文件。 socket是可读可写可控可关闭的文件描述符
1.创建socket
#include<sys/types.h> #include<sys/socket.h> int socket(int domain,int type,int protocol); socket系统调用成功时返回一个socket文件描述符
- domain 告诉系统使用哪个底层协议族 对于tcp/ip PF_INET
- type 服务类型 SOCK_STREAM(数据流 SOCK_DGRAM(数据报
- protocol 0 使用默认协议
2.命名socket
#include<sys/types.h> #include<sys/socket.h> int bind(int sockfd,const struct sockaddr*my_addr,socklen_t addrlen);
-
bind将my_addr所指的socket地址分配给未命名的sockfd文件描述
符,addrlen参数指出该socket地址的长度。 - 通常服务器需要命名socket (只有命名后 客户端才知道如何连接
3.监听socket
#include<sys/socket.h> int listen(int sockfd,int backlog);
- sockfd参数指定被监听的socket
-
backlog参数提示内核监听队列的最大长度 (通常5(超过backlog 服务器不受理新的客户连接
4.接受连接
- 从listen监听队列中接受一个连接
#include<sys/types.h> #include<sys/socket.h> int accept(int sockfd,struct sockaddr*addr,socklen_t*addrlen);// accept成功时返回一个新的连接socket,该socket唯一地标识了被接
- sockfd参数是执行过listen系统调用的监听socket
-
addr参数用来获取被接受连接的远端socket地址
-
该socket地址的长度由addrlen参数指出
5.发起连接
- 客户端主动与服务器建立连接
#include<sys/types.h> #include<sys/socket.h> int connect(int sockfd,const struct sockaddr*serv_addr,socklen_t addrlen);
- sockfd参数由socket系统调用返回一个socket
-
serv_addr参数是服务器监听的socket地址,addrlen参数则指定这个地址的长度
- connect成功时返回0。一旦成功建立连接,sockfd就唯一地标识了
- 这个连接,客户端就可以通过读写sockfd来与服务器通信。connect失败
- 则返回-1并设置errno。其中两种常见的errno是ECONNREFUSED和
- ETIMEDOUT
6.关闭连接
- 关闭一个连接实际上就是关闭该连接对应的socket
#include<unistd.h> int close(int fd);
- fd参数是待关闭的socket
- 并非立即关闭 通过将fd的引用计数-1 0真正关闭
立即终止连接(不通过引用计数
- 可以使用shutdown
#include<sys/socket.h> int shutdown(int sockfd,int howto);
- sockfd参数是待关闭的socket
- howto参数决定了shutdown
7.TCP数据读写
- recv读取sockfd上的数据 send 往sockfd写数据
- buf和len参数分别指定读缓冲区的位置和大小
- flags参数的含义见后文,通常设置为0即可
- recv成功时 返回实际读取到的数据长度
8.UDP数据读写
#include<sys/types.h> #include<sys/socket.h> ssize_t recvfrom(int sockfd,void*buf,size_t len,int flags,struct sockaddr*src_addr,socklen_t*addrlen); ssize_t sendto(int sockfd,const void*buf,size_t len,int flags,const struct sockaddr*dest_addr,socklen_t addrlen);
- recvfrom /sendto读/写sockfd上的数据
- buf和len参数分别指定读缓冲区的位置大小
- 每次读取数据都需要获取发送端的socket地址 src_addr
- addrlen参数指定该地址的长度
- flags参数以及返回值的含义均与send/recv系统调用 的flags相同