TCP协议的通信小程序
TCP协议通信流程
SYN:同步序列编号(Synchronize Sequence Numbers)。是TCP/IP建立连接时使用的握手信号。在客户机和服务器之间建立正常的TCP网络连接时,客户机首先发出一个SYN消息,服务器使用SYN+ACK应答表示接收到了这个消息,最后客户机再以ACK消息响应。这样在客户机和服务器之间才能建立起可靠的TCP连接,数据才可以在客户机和服务器之间传递。
当服务端与客户端之间的连接建立成功之后,与UDP协议不同的时候,TCP协议的通信双方都可以先给对方发送数据。比如说:客户端可以先给服务端发数据,服务端也可以给客户端发送数据。
TCP协议的函数接口
与UDP协议不同的是,TCP协议多了一个监听的过程,而创建套接字和绑定ip和端口信息都是相同的接口。
监听接口 listen
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
- sockfd:套接字描述符
- backlog:已完成连接队列的大小
backlog
可以指定已完成连接队列的大小,如果已完成连接的队列已经满了,就会丢弃掉其他新来的连接
这里有一个服务端需要注意的是,假如有人恶意进行攻击,使用大量随机的ip地址,然后连接服务端,服务端就会向客户端发送确认的请求ACK + SYN
。这时由于源地址可能是不存在的,就会造成服务端不断发送连接请求直到超时。
这就造成了虚假的SYN
包占用了大量的未完成连接队列,使得正常的信息被丢弃,很容易造成崩溃。
接收连接 accept
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
- sockfd:套接字描述符。是他侦听的客户端的sockfd,从侦听的sockfd接收新的连接请求
- addr:客户端的信息结构体
- addrlen:客户端信息结构体的大小
- 返回值:返回的是新创建的socket,然后通过拷贝信息后新创建的socket和客户端进行数据收发
注意 :因为该接口是从已完成连接的队列中获取新的连接。所以,当已连接队列中没有已经完成的新连接的时候,该接口被调用时就会阻塞,直到获取一个新的已完成连接的到来
- 思考:为什么需要用新创建的socket和客户端进行通信?
如果只有一个socket,那么首先就是在他完成连接之并建立通信之后,不能再接收其他新的连接了。
另一个就是他不能区分是哪一个客户端发送的数据了。
connect
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
- socket:套接字描述符
- addr:服务端地址信息,需要自己填充完整,然后传递给connect
- addrlen:地址信息长度
关闭套接字
int close(int fd);
没错,还是close
发送数据
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf,
size_t len, int flags);
- sockfd:套接字描述符,accept函数的返回值
- buf:需要发送的数据
- len:发送数据的长度
- flag:0–>阻塞发送
接收数据
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf,
size_t len, int flags);
- sockfd:套接字描述符,accept函数的返回值
- buf:接收数据存放的位置
- len:最大接收数据的长度
- flag:0–>阻塞发送,
MSG_PEEK
–>探测接收 - 返回值:
大于0:接收了多少字节的数据
等于0:表示对端关闭了连接,也就是对端使用了close接口
小于0:接收失败
MSG_PEEK
,探测接收和阻塞接收的区别:
MSG_PEEK
,探测接收会从接收缓冲区中复制数据到应用层,但是并不会删除接收缓冲区中的数据。
阻塞接收也会从缓冲区中复制数据到应用层,但是他会删除接收缓冲区中的数据。
TCP通信小程序
功能
客户端:
- 创建套接字
- 绑定地址信息,一般不这样弄
- 发起连接
- 发送数据
- 接收数据
- 关闭连接
服务端:
- 创建套接字
- 绑定地址信息
- 监听
- 获取连接
- 发送数据
- 接收数据
- 关闭连接
流程图
程序
tcpClass.hpp
#pragma once
#include <stdio.h>
#include <stdlib.h>