UDP协议 sendto 和 recvfrom 浅析与示例
UDP(user datagram protocol)用户数据报协议,属于传输层。
UDP是面向非连接的协议,它不与对方建立连接,而是直接把数据报发给对方。UDP无需建立类如三次握手的连接,使得通信效率很高。因此UDP适用于一次传输数据量很少、对可靠性要求不高的或对实时性要求高的应用场景。
UDP通信的过程如图所示:
服务端:
(1)使用函数socket(),生成套接字文件描述符;
(2)通过struct sockaddr_in 结构设置服务器地址和监听端口;
(3)使用bind() 函数绑定监听端口,将套接字文件描述符和地址类型变量(struct sockaddr_in )进行绑定;
(4)接收客户端的数据,使用recvfrom() 函数接收客户端的网络数据;
(5)向客户端发送数据,使用sendto() 函数向服务器主机发送数据;
(6)关闭套接字,使用close() 函数释放资源;
客户端:
(1)使用socket(),生成套接字文件描述符;
(2)通过struct sockaddr_in 结构设置服务器地址和监听端口;
(3)向服务器发送数据,sendto() ;
(4)接收服务器的数据,recvfrom() ;
(5)关闭套接字,close() ;
(关于 sockaddr 与 sockaddr_in 的区别,可参考:https://blog.csdn.net/qingzhuyuxian/article/details/79736821)
sendto()
int sendto(int s, const void *buf, int len, unsigned int flags,
const struct sockaddr *to, int tolen);
返回值说明:
成功则返回实际传送出去的字符数,失败返回-1,错误原因会存于errno 中。
参数说明:
s: socket描述符;
buf: UDP数据报缓存区(包含待发送数据);
len: UDP数据报的长度;
flags:调用方式标志位(一般设置为0);
to: 指向接收数据的主机地址信息的结构体(sockaddr_in需类型转换);
tolen:to所指结构体的长度;
recvfrom()
int recvfrom(int s, void *buf, int len, unsigned int flags,
struct sockaddr *from, int *fromlen);
返回值说明:
成功则返回实际接收到的字符数,失败返回-1,错误原因会存于errno 中。
参数说明:
s: socket描述符;
buf: UDP数据报缓存区(包含所接收的数据);
len: 缓冲区长度。
flags: 调用操作方式(一般设置为0)。
from: 指向发送数据的客户端地址信息的结构体(sockaddr_in需类型转换);
fromlen:指针,指向from结构体长度值。
示例代码
服务端
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h> #define MAXLINE 4096
#define UDPPORT 8001
#define SERVERIP "192.168.255.129" using namespace std; int main(){
int serverfd;
unsigned int server_addr_length, client_addr_length;
char recvline[MAXLINE];
char sendline[MAXLINE];
struct sockaddr_in serveraddr , clientaddr; // 使用函数socket(),生成套接字文件描述符;
if( (serverfd = socket(AF_INET, SOCK_DGRAM, )) < ){
perror("socket() error");
exit();
} // 通过struct sockaddr_in 结构设置服务器地址和监听端口;
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(UDPPORT);
server_addr_length = sizeof(serveraddr); // 使用bind() 函数绑定监听端口,将套接字文件描述符和地址类型变量(struct sockaddr_in )进行绑定;
if( bind(serverfd, (struct sockaddr *) &serveraddr, server_addr_length) < ){
perror("bind() error");
exit();
} // 接收客户端的数据,使用recvfrom() 函数接收客户端的网络数据;
client_addr_length = sizeof(sockaddr_in);
int recv_length = ;
recv_length = recvfrom(serverfd, recvline, sizeof(recvline), , (struct sockaddr *) &clientaddr, &client_addr_length);
cout << "recv_length = "<< recv_length <<endl;
cout << recvline << endl; // 向客户端发送数据,使用sendto() 函数向服务器主机发送数据;
int send_length = ;
sprintf(sendline, "hello client !");
send_length = sendto(serverfd, sendline, sizeof(sendline), , (struct sockaddr *) &clientaddr, client_addr_length);
if( send_length < ){
perror("sendto() error");
exit();
}
cout << "send_length = "<< send_length <<endl; //关闭套接字,使用close() 函数释放资源;
close(serverfd); return ;
}
客户端
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h> #define MAXLINE 4096
#define UDPPORT 8001
#define SERVERIP "192.168.255.129" using namespace std; int main(){
int confd;
unsigned int addr_length;
char recvline[MAXLINE];
char sendline[MAXLINE];
struct sockaddr_in serveraddr; // 使用socket(),生成套接字文件描述符;
if( (confd = socket(AF_INET, SOCK_DGRAM, )) < ){
perror("socket() error");
exit();
} //通过struct sockaddr_in 结构设置服务器地址和监听端口;
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(SERVERIP);
serveraddr.sin_port = htons(UDPPORT);
addr_length = sizeof(serveraddr); // 向服务器发送数据,sendto() ;
int send_length = ;
sprintf(sendline,"hello server!");
send_length = sendto(confd, sendline, sizeof(sendline), , (struct sockaddr *) &serveraddr, addr_length);
if(send_length < ){
perror("sendto() error");
exit();
}
cout << "send_length = " << send_length << endl; // 接收服务器的数据,recvfrom() ;
int recv_length = ;
recv_length = recvfrom(confd, recvline, sizeof(recvline), , (struct sockaddr *) &serveraddr, &addr_length);
cout << "recv_length = " << recv_length <<endl;
cout << recvline << endl; // 关闭套接字,close() ;
close(confd); return ;
}
UDP协议 sendto 和 recvfrom 浅析与示例的更多相关文章
- (十四)UDP协议的两个主要方法sendto和recvfrom详解
在网络编程中,UDP运用非常广泛.很多网络协议是基于UDP来实现的,如SNMP等.大家常常用到的局域网文件传输软件飞鸽传书也是基于UDP实现的. 本篇文章跟大家分享linux下UDP的使用和实现,主要 ...
- 网络编程 UDP协议 TCP局域网客户端与服务端上传下载电影示例
UDP协议 (了解) 称之为数据包协议,又称不可靠协议. 特点: 1) 不需要建立链接. 2) 不需要知道对方是否收到. 3) 数据不安全 4) 传输速度快 5)能支持并发 6) 不会粘包 7) 无需 ...
- UDP中的sendto 与recvfrom
sendto 头文件: #include <sys/types.h> #include <sys/socket.h> 定义函数: int sendto(int s, con ...
- 基于UDP协议的socket编程
UDP协议特点: 1.无连接.服务端与客户端传输数据之前不需要进行连接,且没有超时重发等机制,只是把数据通过网络发送出去.也正是因为此特点,所以基于UDP协议的socket的客户端在启动之前不需要先启 ...
- 网络编程----socket介绍、基于tcp协议的套接字实现、基于udp协议的套接字实现
一.客户端/服务器架构(C/S架构) 即C/S架构,包括: 1.硬件C/S架构(打印机) 2.软件C/S架 ...
- 网络编程基础之粘包现象与UDP协议
一.粘包现象原理分析 1.我们先来看几行代码,从现象来分析: 测试程序分为两部分,分别是服务端和客户端 服务端.py #!/usr/bin/env python3 #-*- coding:utf-8 ...
- 网络编程基础:粘包现象、基于UDP协议的套接字
粘包现象: 如上篇博客中最后的示例,客户端有个 phone.recv(2014) , 当服务端发送给客户端的数据大于1024个字节时, 多于1024的数据就会残留在管道中,下次客户端再给服务端发命令时 ...
- 基于UDP协议的socket套接字编程
目录 一.UDP套接字简单示例 1.1 服务端 二.客户端 三.UPD套接字无粘包问题 3.1 服务端 3.2 客户端 四.qq聊天 4.1 服务端 4.2 客户端1 4.3 客户端2 4.4 运行结 ...
- 网络编程之基于UDP协议的套接字编程、基于socketserver实现并发的socket
目录 基于UDP协议的套接字编程 UDP套接字简单示例 服务端 客户端 基于socketserver实现并发的socket 基于TCP协议 server类 request类 继承关系 服务端 客户端1 ...
随机推荐
- Docker的安装和操作(虚拟机+linux系统)
1.简介 Docker是一个开源的应用容器引擎:是一个轻量级容器技术: Docker支持将软件编译成一个镜像:然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像: 运行中的这 ...
- day27 综合架构 rsync备份服务
sync软件使用方法: rsync命令 1v4 a 本地备份数据 cp [root@nfs01 backup]# cp /etc/hosts /tmp [root@nfs01 backup]# ll ...
- LED Craft Light - How To Solve: Home Decoration Lighting
Home décor usually comes with a certain period of theme or a specific style of furniture, which will ...
- EF CodeFirst 一对一、一对多、多对多关系
一对一关系 如图,无需专门指定,系统会默认在Person表中生成字段Pet_Id为Pet表的外键(一对一). Require:必要的(一对一) Optional:可选的(一对零) Principa ...
- Learn from Niu 2020.1.21
1. 你一定要看计算机领域的文章. 如果你是看一堆应用,你最终还是会不知道怎么做. 从计算机到energy是降维打击, 当你学习了计算机的hot skill,再去做应用很容易. 2. 搞研究的思路: ...
- (转)HDFS简介
转自:http://os.51cto.com/art/201212/369564.html
- java 中使用MD5加密 , 入库时对密码进行加密
import lombok.extern.slf4j.Slf4j; import java.security.MessageDigest; @Slf4j public class MD5Util { ...
- 【转载】 __declspec(dllexport) 和__declspec(dllimport)
转自:http://www.cppblog.com/Dutyboy/archive/2010/11/15/133699.html __declspec(dllexport) __declspec( ...
- java fastjson:Map与json以及JSONObject ,JSONObject与String互转
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson ...
- ajax post
前端 $.post("url",JSON.stringify({ a:a, ... }), function(data){ }, 'json'); 后端 @PostMapping( ...