当前位置: 首页 > article >正文

UDP协议的两个主要方法sendto和recvfrom详解

在网络编程中,UDP运用非常广泛。很多网络协议是基于UDP来实现的,如SNMP等。大家常常用到的局域网文件传输软件飞鸽传书也是基于UDP实现的。

本篇文章跟大家分享linux下UDP的使用和实现,主要介绍下sendto()和recvfrom()两个函数的使用,以及INADDR_ANY的说明,并在最后展示了一个经过自己测试可用的UDP Server和UDP Client的代码示例。

关于UDP数据报

UDP都是以数据报的形式进行发送和接收的,而TCP是以数据流的形式进行发送和接收的。数据报和数据流,这两者要区分开来。

头文件

#include <sys/types.h>
#include <sys/socket.h>

函数原型

int sendto (int s, const void *buf, int len, unsigned int flags, const struct sockaddr *to, int tolen);

int recvfrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen);

函数说明

sendto(),是把UDP数据报发给指定地址;recvfrom()是从指定地址接收UDP数据报。

参数说明

  • \s:            socket描述符。
  • \buf:         UDP数据报缓存地址。
  • \len:         UDP数据报长度。
  • \flags:       该参数一般为0。
  • \to:           sendto()函数参数,struct sockaddr_in类型,指明UDP数据发往哪里报。
  • \tolen:       对方地址长度,一般为:sizeof(struct sockaddr_in)。
  • \from:   recvfrom()函数参数,struct sockaddr 类型,指明UDP数据从哪里收。  
  • \fromlen:recvfrom()函数参数,struct sockaddr_in类型,指明从哪里接收UDP数据报。

函数返回值

对于sendto()函数,成功则返回实际传送出去的字符数,失败返回-1,错误原因存于errno 中。

对于recvfrom()函数,成功则返回接收到的字符数,失败则返回-1,错误原因存于errno中。

UDP Server和Client源码实例

UDP Server:

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <unistd.h>

#include <stdlib.h>

#include <string.h>

#include <stdio.h>

 

#defineUDP_TEST_PORT50001

 

int main(int argC, char* arg[])

{

struct sockaddr_in addr;

int sockfd, len = 0;

int addr_len = sizeof(struct sockaddr_in);

char buffer[256];

 

/* 建立socket,注意必须是SOCK_DGRAM */

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {

perror ("socket");

exit(1);

}

 

/* 填写sockaddr_in 结构 */

bzero(&addr, sizeof(addr));

addr.sin_family = AF_INET;

addr.sin_port = htons(UDP_TEST_PORT);

addr.sin_addr.s_addr = htonl(INADDR_ANY) ;// 接收任意IP发来的数据

 

/* 绑定socket */

if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr))<0) {

perror("connect");

exit(1);

}

 

while(1) {

bzero(buffer, sizeof(buffer));

len = recvfrom(sockfd, buffer, sizeof(buffer), 0, 

  (struct sockaddr *)&addr ,&addr_len);

/* 显示client端的网络地址和收到的字符串消息 */

printf("Received a string from client %s, string is: %s\n", 

inet_ntoa(addr.sin_addr), buffer);

/* 将收到的字符串消息返回给client端 */

sendto(sockfd,buffer, len, 0, (struct sockaddr *)&addr, addr_len);

}

 

return 0;

}

 

// ----------------------------------------------------------------------------

// End of udp_server.c

UDP Client:

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <unistd.h>

#include <stdlib.h>

#include <string.h>

#include <stdio.h>

 

#defineUDP_TEST_PORT50001

#define UDP_SERVER_IP "127.0.0.1"

 

int main(int argC, char* arg[])

{

struct sockaddr_in addr;

int sockfd, len = 0;

int addr_len = sizeof(struct sockaddr_in);

char buffer[256];

 

/* 建立socket,注意必须是SOCK_DGRAM */

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {

perror("socket");

exit(1);

}

 

/* 填写sockaddr_in*/

bzero(&addr, sizeof(addr));

addr.sin_family = AF_INET;

addr.sin_port = htons(UDP_TEST_PORT);

addr.sin_addr.s_addr = inet_addr(UDP_SERVER_IP);

 

while(1) {

bzero(buffer, sizeof(buffer));

 

printf("Please enter a string to send to server: \n");

 

/* 从标准输入设备取得字符串*/

len = read(STDIN_FILENO, buffer, sizeof(buffer));

 

/* 将字符串传送给server端*/

sendto(sockfd, buffer, len, 0, (struct sockaddr *)&addr, addr_len);

 

/* 接收server端返回的字符串*/

len = recvfrom(sockfd, buffer, sizeof(buffer), 0, 

      (struct sockaddr *)&addr, &addr_len);

printf("Receive from server: %s\n", buffer);

}

 

return 0;

}

 

// ----------------------------------------------------------------------------

 

// End of udp_client.c

UDP Server:

01 #include <sys/types.h>
02 #include <sys/socket.h>
03 #include <netinet/in.h>
04 #include <arpa/inet.h>
05 #include <unistd.h>
06 #include <stdlib.h>
07 #include <string.h>
08 #include <stdio.h>
09  
10 #define UDP_TEST_PORT       50001
11  
12 int main(int argC, char* arg[])
13 {
14     struct sockaddr_in addr;
15     int sockfd, len = 0;   
16     int addr_len = sizeof(struct sockaddr_in);
17     char buffer[256];  
18  
19     /* 建立socket,注意必须是SOCK_DGRAM */
20     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
21         perror ("socket");
22         exit(1);
23     }
24  
25     /* 填写sockaddr_in 结构 */
26     bzero(&addr, sizeof(addr));
27     addr.sin_family = AF_INET;
28     addr.sin_port = htons(UDP_TEST_PORT);
29     addr.sin_addr.s_addr = htonl(INADDR_ANY) ;// 接收任意IP发来的数据
30  
31     /* 绑定socket */
32     if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr))<0) {
33         perror("connect");
34         exit(1);
35     }
36  
37     while(1) {
38         bzero(buffer, sizeof(buffer));
39         len = recvfrom(sockfd, buffer, sizeof(buffer), 0,
40                        (struct sockaddr *)&addr ,&addr_len);
41         /* 显示client端的网络地址和收到的字符串消息 */
42         printf("Received a string from client %s, string is: %s\n",
43                 inet_ntoa(addr.sin_addr), buffer);
44         /* 将收到的字符串消息返回给client端 */
45         sendto(sockfd,buffer, len, 0, (struct sockaddr *)&addr, addr_len);
46     }
47  
48     return 0;
49 }
50  
51 // ----------------------------------------------------------------------------
52 // End of udp_server.c

UDP Client:

view source
 
01 #include <sys/types.h>
02 #include <sys/socket.h>
03 #include <netinet/in.h>
04 #include <arpa/inet.h>
05 #include <unistd.h>
06 #include <stdlib.h>
07 #include <string.h>
08 #include <stdio.h>
09  
10 #define UDP_TEST_PORT       50001
11 #define UDP_SERVER_IP       "127.0.0.1"
12  
13 int main(int argC, char* arg[])
14 {
15     struct sockaddr_in addr;
16     int sockfd, len = 0;   
17     int addr_len = sizeof(struct sockaddr_in);     
18     char buffer[256];
19  
20     /* 建立socket,注意必须是SOCK_DGRAM */
21     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
22         perror("socket");
23         exit(1);
24     }
25  
26     /* 填写sockaddr_in*/
27     bzero(&addr, sizeof(addr));
28     addr.sin_family = AF_INET;
29     addr.sin_port = htons(UDP_TEST_PORT);
30     addr.sin_addr.s_addr = inet_addr(UDP_SERVER_IP);
31  
32     while(1) {
33         bzero(buffer, sizeof(buffer));
34  
35         printf("Please enter a string to send to server: \n");
36  
37         /* 从标准输入设备取得字符串*/
38         len = read(STDIN_FILENO, buffer, sizeof(buffer));
39  
40         /* 将字符串传送给server端*/
41         sendto(sockfd, buffer, len, 0, (struct sockaddr *)&addr, addr_len);
42  
43         /* 接收server端返回的字符串*/
44         len = recvfrom(sockfd, buffer, sizeof(buffer), 0,
45                        (struct sockaddr *)&addr, &addr_len);
46         printf("Receive from server: %s\n", buffer);
47     }
48  
49     return 0;
50 }
51  
52 // ----------------------------------------------------------------------------
53 // End of udp_client.c

上述代码是经过验证可用的。

http://www.lryc.cn/news/2417107.html

相关文章:

  • 猫头虎分享已解决Bug || 代理服务器错误(Proxy Server Error):ProxyFailure, ProxyConnectionRefused
  • 【虚幻引擎】UE4 同步和异步资源加载(软引用)
  • Android设备唯一标识(终极方案!)
  • weak reference的介绍
  • yumdownloader介绍和使用示例
  • 正则表达式语法及使用
  • DM脚本启动报错:please change nobody or root to execute the service script,otherwise may be failed
  • USBKEY全解析---概要介绍
  • Java 程序的运行环境及示例代码
  • 日志过滤实体中的属性
  • EtherCAT运动控制卡开发教程之Qt(上):开发环境配置与简单运动控制应用
  • usb一致性测试软件,USB 3.0一致性测试方法
  • EasyExcel 样式注解大全
  • 【计算机网络】网络安全知识要点
  • 【MATLAB安装教学】图文并茂手把手教学
  • OTN技术
  • ShareSDK Android SDK第三方平台分享参数说明
  • 概念模型与E-R模型
  • linux samba 不设权限,centos下Samba配置 解决没有权限问题
  • GD32F303固件库开发(8)----USART收发配置
  • GoldenDict:一款免费的词典工具
  • mysql tdb数据库_MYSQL数据库基础
  • 指针函数的概念
  • 网格组布局管理器(GridBagLayout)网格包布局管理器
  • 什么是串联谐振和并联谐振,有什么作用(硬件每日一题)
  • CSS——FC(BFC/IFC/FFC/GFC)超详细版+原理案例分析
  • Android将library代码发布到jcenter
  • 机器学习——多元线性回归分析(multiple regression)及应用
  • C语言(五)---函数
  • Javascript的调试利器:Firebug使用详解