目录
前言
TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于流的通信协议。它是互联网协议栈(TCP/IP)中的核心协议之一,主要用于保证在计算机网络中可靠地传输数据。
本小节我们先来实现TCP通信,然后再来细分TCP通信当中的一些细节问题,关于tcp的三次握手和四次挥手看这篇文章:http://t.csdnimg.cn/WWgfZ
一、实现TCP通信
服务器代码:
//实现TCP服务器文件
#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>
#include<fcntl.h>
int main(int argc, const char *argv[])
{
//1、创建套接字
int listenfd=socket(AF_INET,SOCK_STREAM,0);
if(listenfd<0)
{
printf("创建失败\n");
return -1;
}
//2、绑定套接字
//填写自己的地址信息,不是必要的
struct sockaddr_in serveraddr;
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(8888);
serveraddr.sin_addr.s_addr=inet_addr("192.168.124.29");
int bind_ret=bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
if(bind_ret<0)
{
printf("绑定失败\n");
return -1;
}
//3、建立连接connect
//监听套接字
int listen_ret=listen(listenfd,10);
if(listen_ret<0)
{
perror("listen failed:");
return -1;
}
//建立连接accept
int serverfd=accept(listenfd,NULL,NULL);
if(serverfd<0)
{
perror("accept failed:");
return -1;
}
while(1)
{
//接收数据
char buf[100];
int ret=recv(serverfd,buf,100,0);
//读取数据发送回去
buf[ret]='\0';
int send_ret=send(serverfd,buf,strlen(buf),0);
if(send_ret<0)
{
perror("send failed:");
return -1;
}
if(send_ret==0)
break;
}
return 0;
}
然后我们使用网络调试器连接服务器:
网络调试器下载地址:通过网盘分享的文件:scomm.exe
链接: https://pan.baidu.com/s/1OkiZLT_CeoryEZepaOSGqQ 提取码: 8a85
如果出现绑定失败如下图:
不用紧张,我们下载号网络调试器之后双击运行;
连接完成之后,在调试器中发送你想要发送的内容,服务器接收到以后,会直接发送到客户端,也就是网络调试器中:
这样我们就完成了一个简单的TCP通信的实现过程
二、通信原理 (网路传输的封包与拆包)
数据在通信过程中的传输我们可以这样来看:
数据经过多次的封装,然后再发送给服务器,再每一层的封装过程中,都会加入一个协议,这个协议帮助数据完整的传输(也就是在我们发送数据的时候加入了网络层-IP头(协议)、传输层-TCP头(TCP协议),网络接口层-帧头(MAC地址)这个就是封包过程,接收端做拆包过程)。下面我们就以TCP传输作为例子。
首先,在客户应用当中我们输入了数据,如上图中的流程图一样,在传输层加入了TCP头,在网络层加入了IP头,在网络接口层加入了MAC帧头,我们仔细来看这些头里面有什么数据。
三、通信过程中的头
上面我们提到了每层中都有协议,那么具体每个协议里面都有什么内容数据呢,本小节我们就来看看里面有什么数据,这里就要用到一个抓包软件wireshark,像自己抓包的小伙伴可以自己下载,
首先,我们打开wireshark这个软件
点击WIAN进入抓包
当我们实现上面TCP服务器的时候,会出现建立连接的过程
1.MAC帧
看图中左下角,我们打开第二行是内核空间封装的MAC帧头地址
里面的信息如下:目标MAC地址(Destination)、源MAC地址(Source),type类型,type后面是十六进制的数,如图中是0X0800则表示只接收本机MAC地址的IPV4类型的数据帧
2. IP头
点击第三行中的数据,这是我们的IP头信息,在下图中可以看到我们使用的IPV4的版本,如下图左下角部分:
3.TCP头
TCP头部是TCP协议中的重要部分,它负责确保数据的可靠传输。TCP头部包含了许多控制信息,用于管理连接、数据流和错误检测。
同样,我们点击第四行,这里面包含了TCP头部的信息,开始部分是我们的源端口号和目的端口号,在左下角部分
4.UDP头
UDP(User Datagram Protocol,用户数据报协议)是一个简单的、无连接的传输层协议。与TCP不同,UDP不提供连接管理、流量控制和错误恢复机制,它更注重于提供快速的、低开销的数据传输。UDP头部设计简单且直接,用于快速传输数据。如下图:
从这里也可以看出UDP通信和TCP通信的区别,我们经常说tcp通信可靠也是因为TCP头中包含数据很多,便于数据传输的完整性,后面我会单独出一篇来介绍