Socket

Socket 起源于 Unix,而 Unix 基本哲学之一就是“一切皆文件”,都可以用 “打开open –> 读写write/read –> 关闭close” 模式来操作。Socket 可以理解为一种特殊的文件。

Socket 的基本操作

socket(...)

//成功返回文件(套接字)描述符;出错返回-1
int socket(int domain, int type, int protocol);

协议族决定了 socket 的地址类型:如 AF_INET 决定了要用ipv4地址(32位)与端口号(16位)的组合、AF_UNIX 决定了要用一个绝对路径作为地址。

bind(...)

当我们调用 socket(domain, type, protocol) 创建一个 socket 时,返回的 socket 描述符存在于协议族(address family,AF_XXX)空间中,但没有一个具体的地址。如果想要给它赋值一个地址(ip+端口),就必须调用 bind() 函数(服务端通常使用),或者调用 connect()listen() 时系统会自动随机分配一个端口(客户端通常使用)。

//成功返回0;出错返回-1
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

通常服务器在启动时都会绑定一个地址(如 127.0.0.1:80 ),客户可以通过这个地址来连接服务器。而客户端就不用指定,系统会自动分配一个端口号和自身 ip 地址组合。这就是为什么通常服务端在 listen() 之前会调用 bind(),而客户端就不用,而是在 connnect() 时由系统随机生成一个。

listen(...)、connect(...) 函数

//sockfd:需要监听的socket
//backlog:该socket可以排队的最大连接数
//成功返回0;失败返回-1
int listen(int sockfd, int backlog);

//sockfd:客户端的socket
//addr:服务器的socket地址
//addrlen:服务器地址长度
//成功返回0;失败返回-1
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

accept(...) 函数

参考:https://blog.csdn.net/zhoucheng05_13/article/details/100162888