Linux学习(14)-socket(套接字)网络编程-tcp协议(传输层)

本节学习内容

1.主机字节序列和网络端字节序列

2.套接字地址结构(1.通用套接字2.专用套接字3.ip地址转换函数)

3.网络编程常用接口

4.TCP编程流程(多进程、多线程处理)

5.TCP(1.TCP协议特点2.TCP协议服务器端与客户端传输流程3.三次握手四次挥手4.流式服务特点(粘包问题)5.TCP的连接状态(TINME_WAIT状态存在的意义))

一、主机字节序列和网络端字节序列

1.数据存储方式

(1)大端存储方式:位字节存储在地址,位字节存储在地址

(2)小端存储方式:位字节存储在地址,位字节存储在地址

2.主机字节序列:不同主机采用的字节序列可能不同,分为大端字节序列和小端字节序列

3.网络字节序列:大端字节序列

二、套接字(socket)地址结构    头:sys/socket.h

1.通用套接字(socketaddr)地址结构

socket网络编程中表示socket地址的是结构体sockaddr(通用套接字)

struct sockaddr

{

    sa_family_t sa_family;

    char as_data[14];

}

2.专用套接字地址结构

(1)TCP/IP协议族中sockaddr_in用于IPV4地址格式,sockaddr_in6用于IPV6地址格式

(2)IPV6地址结构体如下

struct in _ addr
 {
      u_int32_t s_ addr;
 };
struct sockaddr _ in

{
     sa _ family _t sin _ family;  //地址族:AF_INET(ipv4地址族)
     u_int16_t sin _ port;            //端口号(大于4096为临时端口号)
     struct in _ addr.sin _ addr;  //服务器端ip地址
};


(3)IPV6地址结构体如下
 struct in6_ addr
{
     unsigned char sa _ addr[16]; // IPV6地址, 要用网络字节序表示

};

 struct sockaddr _in6
{
     sa _ family _t sin6_ family; // 地址族: AF_INET6
     u_inet16_t sin6_ port; // 端口号: 用网络字节序表示
     u_int32_t sin6_ flowinfo;// 流信息, 应设置为0
     struct in6_ add r sin6_ addr; // IPV6地址结构体
     u_int32_t sin6_ scope _ id; // scope ID, 尚处于试验阶段

};

3.ip地址转换函数  头:arpa/inet.h

一般情况下,用点分十进制字符串表示IPV4地址,但编程需要转化为整数才能使用

所以:

in_addr_t inet_addr(const char*cp);  //字符串表示的IPV4地址(点分十进制)转换为网络字节序列(无符号整型)

char* inet_ntoa(struct in_addr in);  //IPV4地址的网络字节序列转化为字符串表示

三、网络编程常用接口

socket()创建套接字

bind()指定套接字使用的ip端口

listen()监听队列以及存储待处理的客户端连接

accept()接收连接,从listen监听的队列中接收一个连接

recv()接收数据

send()发送数据

close()关闭连接

connect()客户端向服务器发送连接请求

四、TCP编程流程编程

多进程多线程并发处理

如何使一个服务器同时接收多个客户端数据?

每次接收连接客户端,服务器端启动一个线程或进程

代码实现如下:

服务器端

 

 

客户端代码如下

运行结果如下

如上所示,两个不同的客户端进程向服务器同时发送内容 

五、TCP协议特点

1.TCP协议特点TCP协议是面向连接的、可靠的、字节流服务(可靠的体现在:应答确认,超时重传,乱序重排,去重)

2.TCP协议服务器端与客户端传输流程

3.三次握手四次挥手

三次握手:(向服务器发送连接(connect):三次握手开始的地方)

四次挥手:(关闭连接(close),四次挥手开始的地方)

4.流式服务特点

(1)

send()执行成功,只能说明将数据成功写入到发送端的发送缓冲区中,并不能说明数据已经发送到了对端。  

recv()从本端的接收缓冲区中读取数据, 如果接收缓冲区中没有数据, 则recv()方法会阻塞。

例如:

(2)TCP粘包

什么是粘包?

多次发送的数据被对方一次收到

怎么解决粘包

方法一:在一段执行发送数据后,紧接着执行一次收数据(不连续发送数据,就不会粘包)

方法二:在解析发送的每个包时,对数据的起始和结论都做标记号

方法三:发送报文时,在报文头部添加长度位来描述该包的大小

5.TCP连接的状态

学习连接的状态前首先要知道tcp报头的6位标志位

(1)tcp报头的6位标志位
□URG 标志,表示紧急指针( urgent pointer) 是否有效。
ACK 标志,表示确认号是否有效。我们称携带ACK 标志的 TCP 报文段为确认报文段。
□PSH标志, 提示接收端应用程序应该立即从TCP 接收缓冲区中读走数据, 为接收后续数据腾出空间(如果应用程序不将接收到的数据读走,它们就会一直停留在 TCP接收缓冲区中)。
□RST 标志,表示要求对方重新建立连接。我们称携带RST 标志的 TCP 报文段为复位报文段。
SYN标志,表示请求建立一个连接。我们称携带SYN标志的 TCP 报文段为同步报文段。
FIN标志, 表示通知对方本端要关闭连接了。我们称携带FIN标志的TCP 报文段为结束报文段。

(2)tcp状态转移

(3)netstst查看状态的指令

(4)

如下图

 

(5)TIME_WAIT状态,如上图我们可知,TIME_WAIT状态是只有主动关闭的一端才会出现的状态。该状态一般持续时间为2个报文生存时间。

TIME_WAIT状态存在的原因

原因1:保证延迟的tcp报文有足够的时间被识别并丢弃

原因2:可靠的终止TCP连接

  • 22
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值