没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
(1)我的CSDN博客主页: https://blog.csdn.net/xiaolong1126626497
1. UDP协议介绍
UDP协议 相对TCP协议来讲属于不可靠协议,UDP协议是广播方式发送数据,没有服务器和客户端的概
念。
在Linux下使用socket创建UDP的套接字时,属性要选择数据报类型 SOCK_DGRAM 。
2. UDP协议发送和接收数据的函数
2.1 recvfrom函数
UDP使用recvfrom()函数接收数据,他类似于标准的read(),但是在recvfrom()函数中要指明数据的目的
地址。
返回值
成功返回接收到数据的长度,负数失败
前三个参数等同于函数read()的前三个参数,flags参数是传输控制标志。最后两个参数类似于accept的
最后两个参数(接收客户端的IP地址)。
2.2 sendto函数
UDP使用sendto()函数发送数据,他类似于标准的write(),但是在sendto()函数中要指明目的地址。
返回值
成功返回发送数据的长度,失败返回-1
前三个参数等同于函数read()的前三个参数,flags参数是传输控制标志。
参数to指明数据将发往的协议地址,他的大小由addrlen参数来指定。
sockfd=socket(AF_INET,SOCK_DGRAM,0);1
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct
sockaddr * from, size_t *addrlen);
1
2
3
#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const
struct sockaddr * to, int addrlen);
1
2
3
2.3 设置套接字属性
setsockopt()函数用于任意类型、任意状态套接口的设置选项值。尽管在不同协议层上存在选项,但本
函数仅定义了最高的“套接口”层次上的选项。选项影响套接口的操作,诸如加急数据是否在普通数据流
中接收,广播数据是否可以从套接口发送等等。
参数
sockfd:标识一个套接口的描述字。
level:选项定义的层次;目前仅支持SOL_SOCKET和IPPROTO_TCP层次。
optname:需设置的选项。
optval:指针,指向存放选项值的缓冲区。
optlen:optval缓冲区的长度。
UDP协议发送数据时,设置具有广播特性: 默认情况下socket不支持广播特性
3. 案例: UDP协议数据收发
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int getsockopt(int sockfd, int level, int optname,void *optval, socklen_t
*optlen);
int setsockopt(int sockfd, int level, int optname,const void *optval,
socklen_t optlen);
1
2
3
4
char bBroadcast=1;
setsockopt(s,SOL_SOCKET,SO_BROADCAST,(const char*)&bBroadcast,sizeof(char));
1
2
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/epoll.h>
#include <poll.h>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#define SEND_MSG "1314520" //发送的数据包
#define PORT 8888 //固定的端口号
int sockfd;
int main(int argc,char **argv)
{
if(argc!=2)
{
printf("./app <广播地址> 当前程序固定的端口号是8888\n");
return 0;
}
/*1. 创建socket套接字*/
sockfd=socket(AF_INET,SOCK_DGRAM,0);
//设置端口号的复用功能
int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
/*2. 绑定端口号与IP地址*/
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT); // 端口号0~65535
addr.sin_addr.s_addr=INADDR_ANY; //inet_addr("0.0.0.0"); //IP地址
if(bind(sockfd,(const struct sockaddr *)&addr,sizeof(struct
sockaddr))!=0)
{
printf("UDP服务器:端口号绑定失败.\n");
return 0;
}
/*3. 接收数据*/
unsigned char buff[1024+1];
int cnt;
struct sockaddr_in client_addr;
socklen_t addrlen=sizeof(struct sockaddr_in);
struct pollfd fds;
fds.fd=sockfd;
fds.events=POLLIN;
while(1)
{
cnt=poll(&fds,1,1000);
if(cnt>0)
{
cnt=recvfrom(sockfd,buff,1024,0,(struct sockaddr
*)&client_addr,&addrlen);
buff[cnt]='\0';
//判断是不是探测包数据
if(strcmp(buff,SEND_MSG)==0)
{
printf("在线好友:%s,%d--
>%s:%d\n",buff,cnt,inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_por
t));
cnt=sendto(sockfd,SEND_MSG,strlen(SEND_MSG),0,(const struct
sockaddr *)&client_addr,sizeof(struct sockaddr));
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
剩余13页未读,继续阅读
资源评论
DS小龙哥
- 粉丝: 4w+
- 资源: 522
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功