佛山做推广网站的,什么网站看电影是免费的,章丘哪里做网站,大淘客做自己网站TCP与UDP:
TCP:
TCP优点#xff1a; 可靠#xff0c;稳定 TCP的可靠体现在TCP在传递数据之前#xff0c;会有三次握手来建立连接#xff0c;而且在数据传递时#xff0c;有确认、窗口、重传、拥塞控制机制#xff0c;在数据传完后#xff0c;还会断开连接用来节约系统…TCP与UDP:
TCP:
TCP优点 可靠稳定 TCP的可靠体现在TCP在传递数据之前会有三次握手来建立连接而且在数据传递时有确认、窗口、重传、拥塞控制机制在数据传完后还会断开连接用来节约系统资源。
TCP缺点 因为TCP的繁琐机制造成了TCP会更慢消耗更多资源效率会比较低
UDP
UDP优点 因为没有TCP这么繁琐的机制即一个无状态的传输协议所以UDP的传输速度回非常快
UDP缺点 不可靠不稳定网速不好容易丢包
TCP
C/S 模式 -- 服务器/客户端模型client/server
server:socket()--bind()---listen()--accept()--recv()--close() 创建套接字--关联接口地址--等待连接--提取连接--收、发--关闭 client:socket()--connect()--send()--close(); 创建套接字--连接--收、发--关闭
三次握手/四次挥手建立/关闭连接
三次握手 两个标志SYN(同步序列编号)标志 ACK确认标志 客户端connect函数 服务器accept函数 第一次握手客户端发SYN表示希望建立连接客户端进入SYN_SENT状态 第二次握手服务端收到后回发SYN-ACK服务端进入SYN_RECEIVED状态 第三次握手客户端收到SYN-ACK回发ACK确认双方进入ESTABLISHED状态 客户端请求 -- 服务端收到请求通知客户端 -- 客户端确认握手结束双方建立连接
四次挥手 FIN结束标志 看谁先发close函数就是谁发起第一次握手 第一次挥手客户端发FIN并进入FIN_WAIT_1状态 第二次挥手服务器收到后发送ACK给客户端并进入CLOSE_WAIT 第三次挥手客户端完成所有数据接收后准备关闭连接发送FINTIME_WAIT状态 第四次挥手服务器收到FIN后发送ACK并关闭所有连接 客户端请求 -- 服务器收到请求通知客户端 -- 接收完所有数据后通知服务器关闭连接 -- 服务器收到请求后关闭连接
注
按照数据本身发送顺序放入缓冲区中 但是数据本身没有边界会出现黏包问题
解决1.加入结束标志发送strlen(buf)1个数据字符串 2.固定大小发的少10或者结构体 3.自定义协议开始结束标志长度
socket
int socket(int domain, int type, int protocol); 功能程序向内核提出创建一个基于内存的套接字描述符
参数domain 地址族PF_INET协议族 AF_INET地址族IPv4 互联网程序 PF_UNIX AF_UNIX 单机程序 type 套接字类型 SOCK_STREAM 流式套接字 》TCP SOCK_DGRAM 用户数据报套接字UDP SOCK_RAW 原始套接字 》IP protocol 协议 -- 0 表示自动适应应用层协议。
返回值成功 返回申请的套接字id 失败 -1
bind
int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen); 功能如果该函数在服务器端调用则表示将参数1相关 的文件描述符文件与参数2 指定的接口地址关联 用于从该接口接受数据。 如果该函数在客户端调用则表示要将数据从 参数1所在的描述符中取出并从参数2所在的接口 设备上发送出去。 注意如果是客户端则该函数可以省略由默认 接口发送数据。 参数sockfd 之前通过socket函数创建的文件描述符套接字id my_addr 是物理接口的结构体指针。表示该接口的信息。 struct sockaddr 通用地址结构 { u_short sa_family; 地址族 char sa_data[14]; 地址信息 }; 转换成网络地址结构如下 struct _sockaddr_in ///网络地址结构 { u_short sin_family; 地址族 u_short sin_port; ///地址端口 struct in_addr sin_addr; ///地址IP char sin_zero[8]; 占位 }; struct in_addr { in_addr_t s_addr; } socklen_t addrlen: 参数2 的长度。 返回值成功 0 失败 -1
listen int listen(int sockfd, int backlog); 功能在参数1所在的套接字id上监听等待链接。把套接字变为监听状态 参数sockfd 套接字id backlog 允许链接的个数。三次握手的排队数 返回值成功 0 失败 -1
accept 功能从已经监听到的队列中取出有效的客户端链接并 接入到当前程序。 参数sockfd 套接字id addr 如果该值为NULL 表示不论客户端是谁都接入。 如果要获取客户端信息则事先定义变量 并传入变量地址函数执行完毕将会将客户端 信息存储到该变量中。 addrlen 参数2的长度如果参数2为NULL则该值 也为NULL 如果参数不是NULLlen; 一定要写成len sizeof(struct sockaddr); 返回值成功 返回一个用于通信的新套接字id 从该代码之后所有通信都基于该id 失败 -1
在connect函数的最后一个参数是socklen_t类型
而在accept函数中最后一个参数是socklen_t *类型
一般在第一次调用socket时取名listenfd只用到listen到该函数时被替换
typedef struct inetaddr *(SA);
int listenfd socket(AF_INET,SOCK_STREAM,0); //第一个创建的套接字文件描述符
int conn connect(listenfd,(SA)cli,len); //connect创建的新描述符
recv
ssize_t recv(int sockfd, void *buf, size_t len, int flags); 功能从指定的sockfd套接字中以flags方式获取长度 为len字节的数据到指定的buff内存中。 参数sockfd 如果服务器则是accept的返回值的新fd 如果客户端则是socket的返回值旧fd buff 用来存储数据的本地内存一般是数组或者 动态内存可以是结构体连续的一段内存即可。 len 要获取的数据长度 flags 获取数据的方式0 表示阻塞接受。
返回值成功 表示接受的数据长度一般小于等于len 失败 -1
send
int send(int sockfd, const void *msg, size_t len, int flags); 功能从msg所在的内存中获取长度为len的数据以flags 方式写入到sockfd对应的套接字中。 参数sockfd用自己的套接字描述符即可send和recv都一样 msg 要发送的消息 len 要发送的消息长度 flags 消息的发送方式。 返回值成功 发送的字符长度 失败 -1
close
close() 关闭指定的套接字id
客户端
socketconnectsendclose
connect
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 功能该函数固定有客户端使用表示从当前主机向目标 主机发起链接请求。 参数sockfd 本地socket创建的套接子id addr 远程目标主机的地址信息。 addrlen: 参数2的长度。 返回值成功 0 失败 -1 在connect函数的最后一个参数是socklen_t类型 而在accept函数中最后一个参数是socklen_t *类型