TCP socket API详解
下面介绍程序中用到的socket API,这些函数都在sys/socket.h中。
socket():
// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
- socket()打开一个网络通讯端口,如果成功的话,就像open()一样返回一个文件描述符;
- 应用程序可以像读写文件一样用read/write在网络上收发数据;
- 如果socket()调用出错则返回-1;
- 对于IPv4,family(域)参数指定为AF_INET;
- 对于TCP协议,type参数指定为SOCK_STREAM,表示面向流的传输协议
- protocol参数指定为0即可。
bind():
// 绑定端口号 (TCP/UDP, 服务器)
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
- 客户端不需要绑定端口号,服务器必须绑定端口号;
- 服务器程序所监听的网络地址和端口号通常是固定不变的,客户端程序得知服务器程序的地址和端口号后 就可以向服务器发起连接; 服务器需要调用bind绑定一个固定的网络地址和端口号;
- bind()成功返回0,失败返回-1。
- bind()的作用是将参数sockfd和myaddr绑定在一起, 使sockfd这个用于网络通讯的文件描述符监听 myaddr所描述的地址和端口号;
listen():
// 开始监听socket (TCP, 服务器)
int listen(int socket, int backlog);
- listen()声明sockfd处于监听状态, 并且最多允许有backlog个客户端处于连接等待状态, 如果接收到更多 的连接请求就忽略, 这里设置不会太大(一般是5);
- backlog不能太大的原因:用一个例子说明:比如说赛格里的饭店人一般都会较多,老板会在外边摆一些凳子让顾客在那坐着排队,如果老板摆上几百个凳子的话,那就没意思了,只适合摆十几个就可以了(即,不能没有,不能太多,是为了提高效率)
- listen()成功返回0,失败返回-1
accept():
// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address, socklen_t* address_len);
- 三次握手完成后, 服务器调用accept()接受连接;
- 如果服务器调用accept()时还没有客户端的连接请求,就阻塞等待直到有客户端连接上来;
- addr是一个传出参数,accept()返回时传出客户端的地址和端口号;
- 如果给addr 参数传NULL,表示不关心客户端的地址;
connect():
// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
- 客户端需要调用connect()连接服务器
- connect和bind的参数形式一致, 区别在于bind的参数是自己的地址, 而connect的参数是对方的地址;
- connect()成功返回0,出错返回-1
socket用完就要关掉,不关的话会导致下次打开会失败。