linux高级编程(TCP)(传输控制协议)

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(acknowledge)(确认)标志

客户端:connect函数 服务器:accept函数

第一次握手:客户端发SYN,表示希望建立连接,客户端进入SYN_SENT状态

第二次握手:服务端收到后回发SYN-ACK,服务端进入SYN_RECEIVED状态

第三次握手:客户端收到SYN-ACK,回发ACK确认,双方进入ESTABLISHED状态

客户端请求 --> 服务端收到请求,通知客户端 --> 客户端确认,握手结束,双方建立连接

四次挥手:

FIN:结束标志

看谁先发close函数,就是谁发起第一次握手

第一次挥手:客户端发FIN,并进入FIN_WAIT_1状态

第二次挥手:服务器收到后,发送ACK给客户端并进入CLOSE_WAIT

第三次挥手:客户端完成所有数据接收后,准备关闭连接,发送FIN,TIME_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;

如果参数不是NULL,&len;

一定要写成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;

客户端:

socket,connect,send,close

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 *类型

相关推荐
2301_801673011 小时前
8.19笔记
网络·安全
wdxylb2 小时前
云原生俱乐部-shell知识点归纳(1)
linux·云原生
飞雪20073 小时前
Alibaba Cloud Linux 3 在 Apple M 芯片 Mac 的 VMware Fusion 上部署的完整密码重置教程(二)
linux·macos·阿里云·vmware·虚拟机·aliyun·alibaba cloud
路溪非溪3 小时前
关于Linux内核中头文件问题相关总结
linux
三坛海会大神5555 小时前
计算机网络参考模型与子网划分
网络·计算机网络
云卓SKYDROID5 小时前
无人机激光测距技术应用与挑战
网络·无人机·吊舱·高科技·云卓科技
Lovyk6 小时前
Linux 正则表达式
linux·运维
Fireworkitte7 小时前
Ubuntu、CentOS、AlmaLinux 9.5的 rc.local实现 开机启动
linux·ubuntu·centos
sword devil9007 小时前
ubuntu常见问题汇总
linux·ubuntu
ac.char7 小时前
在CentOS系统中查询已删除但仍占用磁盘空间的文件
linux·运维·centos