[网络篇] socket编程

您所在的位置:网站首页 udp发送数据之前不需要建立连接 [网络篇] socket编程

[网络篇] socket编程

2023-12-08 23:03| 来源: 网络整理| 查看: 265

一、初识UDP 1.UDP 协议 UDP 是无连接的,即发送数据之前不需要建立连接(发送数据结束时也没有连接可释放),减少了开销和发送数据之前的时延UDP 使用尽最大努力交付,即不保证可靠交付,主机不需要维持复杂的连接状态表(如发短信,你无法确定对方是否收到)UDP 是面向报文的,发送方的 UDP 对应用程序交下来的报文,在添加首部后就向下交付 IP 层。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界UDP 没有拥塞控制,网络出现的拥塞不会使源主机的发送速率降低。这对某些实时应用是很重要的UDP 支持一对一、一对多、多对一和多对多的交互通信UDP 的首部开销小,只有8个字节,比 TCP 的20个字节的首部要短 2.UDP头

源端口:在需要对方回信时1,不需要时可用全0

目标端口:这在终点交付报文时必须使用

长度:UDP 用户数据报的长度,其最小值是8(仅有首部)

校验和: 检测 UDP 用户数据报在传输中是否有错。有错就丢弃

3.UDP通信过程

 二、UDP通信——scoket编程

UDP网络通信(类似发送/接收短信):

类比

作用

功能

函数

有手机

有网络通信协议UDP

创建套接字文件

socket()

有手机卡(号码)

通信协议中需要有自己的网络信息

绑定(指定)本地当前进程的网络信息

bind()

填写对方手机号,发送短信

使用协议发送数据

协议中添加对方信息发送数据(ip端口)

sendto()

接收短信

使用协议接收数据

根据解析的信息接收数据

recvfrom()

关闭

不再进行通信

关闭通信

close()

1. 创建套接字

#include

#include

//创建套接字文件,为进程添加一个对应的网络通信协议(文件),返回值就是创建号的文件描述符(socket描述符就代表一套协议---套接字)

int socket(int domain, int type, int protocol);

参数1:

int domain:地址族,选用那种网络层协议地址 AF_INET------IPV4 AF_INET6------IPV6

参数2:

int type:套接字类型 SOCK_STREAM--------TCP SOCK_DGRAM---------UDP SOCK_RAW:原始套接字(没有传输层协议)

参数3:

int protocol:套接字协议   0:套接字默认协议

返回值:

int:整数---------文件描述符(套接字文件) 成功:返回套接字描述符 >= 0 失败:返回-1 2.绑定套接字

#include /* See NOTES */

#include

//绑定本地网络信息到套接字中

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

参数1:

int sockfd:绑定本地网络信息到哪个套接字上(绑定到哪一套协议上)

参数2:

const struct sockaddr *addr:结构体地址,这个结构体中存储的本地网络信息(要绑定的网络信息ip、port) struct sockaddr {//通用结构体,表示一个网络信息内容 sa_family_t sa_family; char sa_data[14]; } //IPV4 网络信息结构体 struct sockaddr_in { sa_family_t sin_family;//地址族 AF_INET in_port_t sin_port;//端口 struct in_addr sin_addr;//结构体变量--ip地址 }; /* Internet address. */ struct in_addr {   uint32_t s_addr;//ipv4地址 };

参数3:

socklen_t addrlen:整数,结构体大小(确定信息结构体的大小)

返回值:

成功:返回0 失败:返回-1 3.发送数据

#include

#include

//使用UDP协议发送数据

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);

参数1:

int sockfd:套接字对象,使用哪个套接字发送数据

参数2:

const void *buf:要发送的数据的内存首地址

参数3:

size_t len:发送的数据的大小

参数4:

int flags:标志 0:阻塞发送

参数5:

const struct sockaddr *dest_addr:发送的目标网络信息

参数6:

socklen_t addrlen:结构体大小

返回值:

成功:返回发送的字节数 失败:返回-1 4.接收数据

#include

 #include

//使用UDP协议接收数据

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);

参数1:

int sockfd:套接字,指定使用哪个套接字来接收(ip,port来进行检测)

参数2:

void *buf:接收的数据的存放的地址

参数3:

size_t len:指定能够接收存储的最大大小

参数4:

int flags:标志 0:阻塞接收

参数5:

struct sockaddr *src_addr:在接收数据时,存储发送方的ip和port,如果不需要写NULL

参数6:

socklen_t *addrlen:存储信息结构体的大小,不需要写NULL

返回值:

成功:返回收到的大小 失败:返回-1 5.关闭套接字

int close(int fd)

三、实现代码: //通过UDP协议,发送数据,接收数据 #include #include #include #include #include #include #include int main() { //1、创建套接字,选择对应的网络通信协议组 int socketfd = socket(AF_INET,SOCK_DGRAM,0);//当前进程使用UDP IP 协议 /* if(socketfd < 0) { return -1; } */ //2、绑定套接字,对套接字添加自己当前进行需要到本地网络信息 struct sockaddr_in addr;//有一个IPV4网络信息结构体 addr.sin_family = AF_INET;//地址族-----IPV4 addr.sin_port = htons(10000);//为当前进程添加的端口号为10000-------主机10000端字节序转换为网络字节序 addr.sin_addr.s_addr = inet_addr("192.168.124.63"); bind(socketfd,(struct sockaddr *)&addr,sizeof(addr)); char buf[20]; memset(buf,0,20);//清空buf struct sockaddr_in dest_addr;//接收方网络信息结构体 dest_addr.sin_family = AF_INET;//地址族-----IPV4 dest_addr.sin_port = htons(2000); dest_addr.sin_addr.s_addr = inet_addr("192.168.124.27"); while(1) { fgets(buf,20,stdin); sendto(socketfd,buf,20,0,(struct sockaddr *)&dest_addr,sizeof(dest_addr));//发送 memset(buf,0,20);//清空buf int num=recvfrom(socketfd,buf,20,0,NULL,NULL); printf("recv size is %d\n",num); printf("data is %s\n",buf); } return 0; }

通信结果如下图所示:



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3