服务端视角的C++从入门到精通(十七)

84 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第26天,点击查看活动详情

socket网络通信中的一些小知识之三

上篇文章讲到了将socket文件描述符和socket地址进行绑定的步骤。

第三步

listen(sock_fd, socket_conf.backlog);

监听相应的socket,并且指定请求连接队列的长度。之所以会有请求连接队列,就是因为可能在短时间内有大量的连接来到server这边,而server这边肯定是只能按照“某种机制”来进行选择处理哪些连接。这里的“某种机制”也就是FIFO机制,也就是先到先服务的原则,就跟我日常生活中的排队一个道理,那么这个队列的长度,就是由listen函数中的第二个参数决定的,多了的连接就会被丢弃掉。

第四步

sin_size = sizeof(struct sockaddr_in);
int conn_fd = accept(sock_fd, (struct sockaddr *)&cli_addr, &sin_size);

这里就是开始等待连接,然后分配连接的文件描述符,建立连接。这里默认是阻塞的调用,也就是在连接到来之前都会等在这条语句处,不向下继续运行。这里不得不提到server端的socket连接与client端的socket连接的区别,那就是server端的连接,一般都是由开发者显式指定的,就比如像上篇文章中提到的IP是0.0.0.0,端口是8888,而client端则是由OS分配的,这也就是为什么一个server的socket可以连好多个client、是多对一的数量关系。

第五步

conn_recv_ret = recv(conn_fd, buf, BUF_SIZE, 0);

这里的buf就是接收数据用的数组,BUF_SIZE就指的是一次性从接收缓冲区读取的字节数,如果不足则会全部读取。recv这个函数既可以是阻塞式的,也可以是非阻塞式的,这个可以由开发者通过参数来自主设置。这里,开发者可以有多种方式实现一次性处理一个连接的多个请求,以及多个连接,这部分内容涉及到多线程的使用,以及还有常见的I/O多路复用技术的应用,这块还可以和Go语言结合起来进行理解。