TCP介绍及TCP网络编程

一、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.c
void 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);
  }
发布了17 篇原创文章 · 获赞 15 · 访问量 5361
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览