04_tcp
创始人
2024-02-01 18:12:27

知识点1【多播】

多播地址:

多播地址向以太网MAC地址的映射

UDP多播工作过程:

多播地址结构体:

多播套接口选项:

知识点2【TCP面向链接编程】

1、创建tcp套接字

2、做为客户端需要具备的条件

3、connect链接服务器的函数

4、send函数

5、recv函数

知识点3【TCP服务器】

做为TCP服务器需要具备的条件

1、listen 函数

2、accept函数

知识点4【TCP的三次握手 四次挥手】

1、TCP的三次握手 客户端 connec函数调用的时候发起

2、四次挥手 调用close 激发 底层发送FIN关闭请求

3、close 关闭套接字

知识点1【多播】

多播:

数据的收发仅仅在同一分组中进行

多播的特点:

1、多播地址标示一组接口

2、多播可以用于广域网使用

在IPv4中,多播是可选的

多播地址:

Pv4的D类地址是多播地址

十进制:224.0.0.1 ~ 239.255.255.254 任意一个IP地址 都代表一个多播组

十六进制:E0.00.00.01 à EF.FF.FF.FE

多播地址向以太网MAC地址的映射

UDP多播工作过程:

总结:1、主机先加入多播组 2、往多播组发送数据

多播地址结构体:

在IPv4因特网域(AF_INET)中,多播地址结构体用如下结构体ip_mreq表示

多播套接口选项:

int setsockopt(int sockfd, int level,int optname,   const void *optval, socklen_t optlen);
成功执行返回0,否则返回-1

level

optname

说明

optval类型

IPPROTO_IP

IP_ADD_MEMBERSHIP

加入多播组

ip_mreq{}

IP_DROP_MEMBERSHIP

离开多播组

ip_mreq{}

只能将自己加入到某个多播组

#include
#include
#include
#include
#include 
#include 
#include 
#include 
//将主机 加入到多播组 224.0.0.2  接受
int main()
{int sockfd = socket(AF_INET, SOCK_DGRAM, 0);//让sockfd有一个固定的IP端口struct sockaddr_in my_addr;bzero(&my_addr,sizeof(my_addr));my_addr.sin_family = AF_INET;my_addr.sin_port = htons(8000);my_addr.sin_addr.s_addr = htonl(INADDR_ANY);bind(sockfd, (struct sockaddr *)&my_addr,sizeof(my_addr));//将192.168.0.111 加入到多播组 224.0.0.2中struct ip_mreq mreq;mreq.imr_multiaddr.s_addr = inet_addr("224.0.0.2");mreq.imr_interface.s_addr = htonl(INADDR_ANY);setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,sizeof(mreq));while(1){unsigned char buf[1500]="";recvfrom(sockfd,buf,sizeof(buf), 0,NULL,NULL);printf("buf=%s\n", buf);}close(sockfd);return 0;
}

 运行结果:

知识点2【TCP面向链接编程】

TCP回顾

1、面向连接的流式协议;可靠、出错重传、且每收到一个数据都要给出相应的确认

2、通信之前需要建立链接

3、服务器被动链接,客户端是主动链接

TCP与UDP的差异:

TCP C/S架构

1、创建tcp套接字

2、做为客户端需要具备的条件

1、知道“服务器”的ip、port

2、Connect主动连接“服务器”

3、需要用到的函数

socket—创建“主动TCP套接字”

connect—连接“服务器”

send—发送数据到“服务器”

recv—接受“服务器”的响应

close—关闭连接

3、connect链接服务器的函数

int connect(int sockfd,const struct sockaddr *addr,socklen_t len);

功能:

主动跟服务器建立链接

参数:

sockfd:socket套接字

addr:   连接的服务器地址结构

len:  地址结构体长度

返回值:

成功:0    失败:其他

注意:

1、connect建立连接之后不会产生新的套接字

2、连接成功后才可以开始传输TCP数据

3、头文件:#include

4、send函数

ssize_t send(int sockfd, const void* buf,size_t nbytes, int flags);

功能:

用于发送数据

参数:

sockfd: 已建立连接的套接字

buf:    发送数据的地址

nbytes:  发送缓数据的大小(以字节为单位)

flags:    套接字标志(常为0)

返回值:

成功发送的字节数

头文件:

#include

5、recv函数

ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);

功能:

用于接收网络数据

参数:

sockfd:套接字

buf: 接收网络数据的缓冲区的地址

nbytes: 接收缓冲区的大小(以字节为单位)

flags: 套接字标志(常为0)

返回值:

成功接收到字节数

头文件:

#include

案例:TCP客户端

#include
#include
#include
#include
#include 
#include 
#include 
#include 
//TCP客户端
int main()
{//创建一个TCP套接字 SOCK_STREAMint sockfd = socket(AF_INET, SOCK_STREAM, 0);printf("sockfd = %d\n", sockfd);//bind是可选的struct sockaddr_in my_addr;bzero(&my_addr,sizeof(my_addr));my_addr.sin_family = AF_INET;my_addr.sin_port = htons(9000);my_addr.sin_addr.s_addr = htonl(INADDR_ANY);bind(sockfd,(struct sockaddr *)&my_addr,sizeof(my_addr));//connect链接服务器struct sockaddr_in ser_addr;bzero(&ser_addr,sizeof(ser_addr));ser_addr.sin_family = AF_INET;ser_addr.sin_port = htons(8000);//服务器的端口ser_addr.sin_addr.s_addr = inet_addr("192.168.0.110");//服务器的IP//如果sockfd没有绑定固定的IP以及端口 在调用connect时候 系统给sockfd分配自身IP以及随机端口connect(sockfd, (struct sockaddr *)&ser_addr,sizeof(ser_addr));//给服务器发送数据 sendprintf("发送的消息:");char buf[128]="";fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]=0;send(sockfd, buf, strlen(buf), 0);//接收服务器数据 recvchar msg[128]="";recv(sockfd, msg,sizeof(msg), 0);printf("服务器的应答:%s\n", msg);//关闭套接字close(sockfd);return 0;
}

运行结果: 

知识点3【TCP服务器】

做为TCP服务器需要具备的条件

1、具备一个可以确知的地址 bind

2、让操作系统知道是一个服务器,而不是客户端 listen

3、等待连接的到来 accpet

对于面向连接的TCP协议来说,连接的建立才真正意味着数据通信的开始.

1、listen 函数

int listen(int sockfd, int backlog);

功能:

将套接字由主动修改为被动。

使操作系统为该套接字设置一个连接队列,用来记录所有连接到该套接字的连接。

参数:

sockfd: socket监听套接字

backlog:连接队列的长度

返回值:

成功:返回0

2、accept函数

int accept(int sockfd,struct sockaddr *cliaddr, socklen_t *addrlen);

功能:

从已连接队列中取出一个已经建立的连接,如果没有任何连接可用,则进入睡眠等待(阻塞)

参数:

sockfd: socket监听套接字

cliaddr: 用于存放客户端套接字地址结构

addrlen:套接字地址结构体长度的地址

返回值:

已连接套接字

头文件:

#include

注意:

返回的是一个已连接套接字,这个套接字代表当前这个连接

#include
#include
#include
#include
#include 
#include 
#include 
#include int main()
{//1、创建一个tcp监听套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);//2、使用bind函数 给监听套接字 绑定固定的ip以及端口struct sockaddr_in my_addr;bzero(&my_addr,sizeof(my_addr));my_addr.sin_family = AF_INET;my_addr.sin_port = htons(8000);my_addr.sin_addr.s_addr = htonl(INADDR_ANY);bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr));//3、使用listen创建连接队列 主动变被动listen(sockfd, 10);//4、使用accpet函数从连接队列中 提取已完成的连接 得到已连接套接字struct sockaddr_in cli_addr;socklen_t cli_len = sizeof(cli_addr);int new_fd = accept(sockfd, (struct sockaddr *)&cli_addr, &cli_len);//new_fd代表的是客户端的连接   cli_addr存储是客户端的信息char ip[16]="";inet_ntop(AF_INET,&cli_addr.sin_addr.s_addr, ip,16);printf("客户端:%s:%hu连接了服务器\n",ip,ntohs(cli_addr.sin_port));//5、获取客户端的请求 以及 回应客户端char buf[128]="";recv(new_fd, buf,sizeof(buf),0);printf("客户端的请求为:%s\n",buf);send(new_fd,"recv", strlen("recv"), 0);//6、关闭已连接套接字close(new_fd);//7、关闭监听套接字close(sockfd);return 0;
}

 运行结果:

知识点4【TCP的三次握手 四次挥手】

1、TCP的三次握手 客户端 connec函数调用的时候发起

SYN是一个链接请求:是TCP报文中的某一个二进制位

第一次握手:客户端 发送SYN请求 链接服务器

第二次握手:服务器 ACK回应客户端的链接请求 同时 服务器给客户端发出链接请求

第三次握手:客户端 ACK回应 服务器的链接请求

2、四次挥手 调用close 激发 底层发送FIN关闭请求

不缺分客户端 或 服务器先后问题。

第一次挥手:A调用close 激发底层 发送FIN关闭请求 并且A处于半关闭状态

第二次挥手:B的底层给A回应ACK 同时导致B的应用层recv/read收到0长度数据包

第三次挥手:B调用close 激发底层给A发送FIN关闭请求 并且B处于半关闭状态

第四次挥手:A的底层给B回应ACK 同时 A处于完全关闭状态,B收到A的ACK也处于完全关闭状态

3、close 关闭套接字

 

相关内容

热门资讯

应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...