TCP介绍及TCP网络编程
来源:互联网 发布:js代码断点调试 编辑:程序博客网 时间:2024/05/19 04:54
一、TCP头部结构:
①16位端口号及16位目的端口号:告知主机该报文段来自哪里(源端口)要传给那个上层协议或应用程序(目的端口)。
②32位序号:一次TCP通信过程中某一个传输方向上的字节流的每个字节的编号。A发送给B的第一个报文段中,序号值被系统初始化为某个随机值ISN,后续在该方向上的TCP报文段的序号值被设置为ISN加上该报文段所携带数据的第一个字节在整个字节流中的偏移。
③32位确认号:另一方对TCP报文段的响应,其值是收到的TCP报文段的序号值加1。
④4位头部长度:标识该TCP头部有多少个32位(4字节,即有多少行)。4位最大能表示15,所以TCP头部最长是60字节。
⑤6位标志:
5.1 URG标志:紧急指针是否有效。
5.2 ACK标志:确认号是否有效。确认报文段。
5.3 PSH标志:提示接收端应用程序应该立即从TCP接受缓冲区中读走数据,为接受后续数据腾出空间。TCP缓冲区 在网卡上,有大小限制,如果应用程序一直不读取就会一直在缓冲区,影响后续数据。
5.4 RST标志:表示要求对方重新建立连接。复位报文段。
5.5 SYN标志:请求建立连接。同步报文段。
5.6 FIN标志:通知对方本段要关闭连接。结束报文段。
⑥16位窗口大小:TCP流量控制。接收通告窗口告诉对方本端的TCP缓冲区还能接收多大字节的数据,避免发过来接收不了而造成的数据丢失。
⑦16位校验和:检验TCP报文段在传输过程中是否损坏。
⑧16位紧急指针:紧急数据先处理。
二、TCP三次握手以及四次挥手(本文都以客户端先发送请求为例)
三次握手建立连接:
①请求连接方(客户端)发送SYN请求连接;
②服务器返回SYN/ACK确认收到发送端请求;
③客户端回馈给服务器ACK,表示确认收到服务器发送的确认。
注:1、如果服务器没有收到客户端发送的ACK,则启动超时重传机制,这确保了TCP连接的准确性。2、TCP的握手至少有三次,不可再少。
四次挥手断开连接:
①请求方(客户端)数据已经发送完毕,向服务器发送FIN请求断开连接;
②服务器向客户端发送ACK,对客户端发送的FIN进行确认,并不需要即使断开;
③服务器将接收到的数据处理完毕后发送FIN,断开连接;
④客户端发送确认消息ACK。
注:1、应答方(服务器)给在请求方(客户端)发送第一个ACK之后,可能还需要一段时间来处理请求方发送的数据。2、如果在应答方(服务器)给请求方(客户端)发送第一个ACK后,服务器可能已经处理完了所有的数据,此时四次挥手可以缩短为三次。3、TIME_WAIT状态:出现在主动发起断开链接请求的一端。意义: 3.1、 保证可靠的终止TCP链接 3.2、 保证迟来的数据报能被识别并丢弃
三、总状态转移图
四、TCP编程
服务器:
1、创建socket
2、bind(命名IP地址和端口号)
3、listen(创建监听队列)
4、accept(拿到已经完成连接的)
5、recv/send(收发数据)
6、close(关闭)
客户端:
1、socket
2、connect
3、recv/send
4、close
①创建套接字函数:int socket(int domain, int type, int protocol)domain:协议簇 IPv4(AF_INET)或 IPv6(AF_INET6) type:选择协议 TCP:SOCK_STREAM UDP:SOCK_DGRAM protocol:0 ②命名IP地址和端口号:int bind(int sockfd,const struct sockaddr*addr,int addrlen)sockfd:文件描述符 addr:指定IP地址和端口号 struct sockaddr_in{ sa_family_t sin_family; //地址簇:AF_INET u_int16_t sin_port; //端口号(网络字节序:大端模式 PC机:小端模式) struct in_addr sin_addr; //IPv4地址结构体}; struct sin_addr{ u_int32_t s_addr; //IPv4地址用网络字节序表示}; addrlen:该socket地址的长度③创建一个监听队列:int listen(int sockfd, int size) size:队列大小,默认值5 。④int accept(int sockfd,struct sockaddr *addr ,int *addrlen)addr:要连接的服务器的ip地址及端口号(netstat -atp 显示本机上所有的tcp服务程序以及其占用的端口号)⑤recv(c,buff,127,0)
代码实现
ser.c
void main() { int sockfd = socket(AF_INET,SOCK_STREAM,0); assert(sockfd != -1); struct sockaddr_in ser,cli; ser.sin_family = AF_INET; ser.sin_port = htons(6000); ser.sin_addr.s_addr = inet_addr("127.0.0.1"); int res = bind(sockfd,(struct sockaddr*)&ser,sizeof(ser)); assert(res != -1); listen(sockfd,5); while(1) { int len = sizeof(cli); int c = accept(sockfd,(struct sockaddr*)&cli,&len); assert(c != -1); char buff[128] = {0}; recv(c,buff,127,0); printf("recv::%s\n",buff); send(c,"I Know",strlen("I Know"),0); close(c); } close(sockfd); }
cli.c
//客户端cli.cvoid main() { int sockfd = socket(AF_INET,SOCK_STREAN,0); assert(sockfd != -1); struct sockaddr_in ser,cli; ser.sin_family = AF_INET; ser.sin_port = htons(6000); ser.sin_addr.s_addr = inet_addr("127.0.0.1"); int res = connect(sockfd,(struct sockaddr*)&ser,sizeof(ser)); assert(res != -1); send(sockfd,"Hello World",strlen("Hello World"),0); char buff[128] = {0}; recv(sockfd,buff,127,0); printf("recv::%s\n",buff); close(sockfd); }
- TCP介绍及TCP网络编程
- Java网络编程——TCP介绍
- TCP网络编程接口详细介绍
- Linux网络编程基础--初等网络函数介绍(TCP)及示例程序
- 网络编程-概念及UDP、TCP连接
- Linux网络编程:2. 初等网络函数介绍(TCP)
- Linux网络编程--2. 初等网络函数介绍(TCP)
- Linux网络编程--初等网络函数介绍(TCP)
- Linux网络编程--2. 初等网络函数介绍(TCP)
- (二)Linux网络编程--初等网络函数介绍(TCP)
- Linux网络编程--初等网络函数介绍(TCP)
- Linux网络编程--初等网络函数介绍(TCP)
- TCP、UDP编程介绍
- TCP/IP网络编程
- TCP/IP网络编程
- dotnet 网络编程 tcp
- 网络编程TCP
- 网络编程 TCP
- 几种集合中查找指定元素的方法的执行效率
- python学习笔记(十五)——集合
- c#线程关闭
- 在vi按了ctrl+s后
- c#自定义控件属性
- TCP介绍及TCP网络编程
- 动态规划问题小结
- 前端学习路径+学习方法+书籍推荐+教学视频分享
- 一个大型高并发系统的性能调优会涉及到什么?
- 设置matplotlib中文显示
- Python可视化库Matplotlib的使用
- oracle常用函数小结(二)
- WatchService——监控硬盘文件改动功能用法及其缺陷
- PyTorch的入门教程实战