2019-11-21实现基于TCP的服务器/客户端

TCP服务器端的默认函数调用顺序

图片来自《TCP/IP网络编程》.png

除了创建套接字,声明并初始化地址信息结构体变量,调用bind函数向套接字分配地址。
接下来还要经过那么几个过程:

进入等待连接请求状态

#include <sys/socket.h>

int listen(int sock,int backlog)
  • sock 希望进入等待请求状态的套接字文件描述符,传递的描述符套接字参数成为服务器端套接字(监听套接字)
  • backlog 连接请求等待队列的长度,若为5,则队列长度为5,表示最多使5个连接请求进入队列。

受理客户端连接请求

调用listen函数后,若有新的连接请求,则应按序受理。受理请求意味着进入可接收数据的状态。这时候需要另外一个套接字,但没必要亲自创建。下面这个函数会自动创建套接字,并连接到发起请求的客户端。

#include <sys/socket.h>
int accept(int sock,struct sockaddr * addr, socklen_t * addrlen);
  • sock 服务器套接字的文件描述符
  • addr 保存发起连接请求的客户端地址信息的变量地址值,调用函数后向传递来的地址变量参数填充客户端地址信息
  • addrlen addr参数的结构体长度,完成调用后改长度即为客户端地址长度

TCP客户端的默认函数调用顺序

图片来自《TCP/IP网络编程》.png

与服务器端相比,区别在于“请求连接”,它是在创建客户端套接字之后向服务器发起的连接请求。该请求需要在服务器端调用listen函数之后

#include <sys/socket.h>
int connect(int sock,struct sockaddr * servaddr,socklen_t addlen); 
  • sock 客户端套接字文件描述符
  • servaddr 保存目标服务器端地址信息的变量地址值
  • addrlen 以字节为单位传递已传递给第二个结构体参数servaddr的地址变量长度
    客户端调用conncet函数后,发生以下情况之一才会返回(完成函数调用):
  1. 服务器端接收连接请求
  2. 发生断网等异常情况而中断连接请求
    需要注意:所谓的“接收连接”并不意味着服务器调用accept函数,其实是服务器端把连接请求信息记录到等待队列。因此connect函数返回后并不立即进行数据交换。

实现服务器端必经过程之一就是给套接字分配IP和端口号。但客户端实现过程中并未出现套接字地址分配,而是创建套接字后立即调用connect函数。并不是客户端套接字无需分配,而是在connect函数中自动分配了。

基于TCP的服务器端/客户端函数调用关系

图片来自《TCP/IP网络编程》.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容