自学嵌入式第三十四天:网络编程-TCP
一、UDP用户数据报
收发次数要对应;
数据与数据之间有边界,多次调用收发时都是不同的数据报;
接收方的数据大小>=发送方的数据大小,如果接受方数据小了则会丢弃未读的部分,再次调用只会读下一包数据;
二、服务器/客户端模型
1.c/s client/server
服务器客户端模型:
客户端是专用的;
可以使用http等标准协议,也可以使用自定义协议;
资源大部分都在cli里,只有必要的交互数据由客户端发;
受到的限制较小,功能相对复杂;
2.b/s browser/server
浏览器客户端模型:
客户端是通用的;
用的是http;
都是客户端发给服务器;
在传输数据过程中受到http的限制,功能不复杂;
3.p2p peer to peer
一般是用于直播;
服务器给传输数据,其他进度快的客户端也给传输数据,如果本客户端进度快也会传输数据给其他客户端;
三、TCP传输控制协议
1.流式套接字,数据是连续的,有顺序的;
可靠传输方式,有链路,有应答机制,如果发送没应答将自动重传;
全双工通信,同一时刻既可以收又可以发,可以同时进行;
双缓冲区,收发互不影响;
2.三次握手:
建立连接:
客户端发送连接请求SYN;
服务端发送连接请求SYN和ACK;
客户端应答ACK建立连接;
3.四次挥手
断开连接:
客户端发送断开请求FIN和ACK;
服务器应答ACK;
服务区发送断开请求FIN和ACK;
客户端应答ACK;
4.缓冲区大小64k,写得太快会写阻塞;
5.socket
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
type:SOCK_STREAM-流式套接字;
6.地址127.0.0.1代表自己,但只能自己通自己;
INADDR_ANY表示全监听,接收所有信息,可以被别人找到;
7.listen
把服务器调成可被链接的状态(监听状态);
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
backlog:同一时刻可以连接的最大个数,第backlog+1个直接被拒绝;
8.accept
阻塞直到有客户端连接;
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
9.recv
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
10.send
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
11.connect
客户端发出连接请求;
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
12.tcp中通过套接字找到地址
#include <sys/socket.h>
int getpeername(int socket,struct sockaddr* addr,socklen_t *addrlen)
13.数据的粘包
发送方发啊送你数据,接收方无法解析数据。
解决:设置边界(eg:\0);固定大小;自定义协议;
四、TCP和UDP的差别
1.UDP无连接,需要写标识退出;
TCP有链接,(三次握手四次挥手)整个通信过程都会保持连接;
2.UDP不可靠,数据有丢包风险;
TCP可靠,数据之间没有边界;
3.UDP数据报,发送次数和接收次数需要对应,数据与数据之间有边界;
TCP流式套接字,次数不必对应;
4.UDP没有拥塞控制;
TCP超时重传;
5.广播、组播只能用UDP;
6.首部开销小;
7.TCP是全双工通信,有双缓冲区,而UDP只有一个缓冲区,某时刻要么收要么发;