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 浅析与示例的更多相关文章

  1. (十四)UDP协议的两个主要方法sendto和recvfrom详解

    在网络编程中,UDP运用非常广泛.很多网络协议是基于UDP来实现的,如SNMP等.大家常常用到的局域网文件传输软件飞鸽传书也是基于UDP实现的. 本篇文章跟大家分享linux下UDP的使用和实现,主要 ...

  2. 网络编程 UDP协议 TCP局域网客户端与服务端上传下载电影示例

    UDP协议 (了解) 称之为数据包协议,又称不可靠协议. 特点: 1) 不需要建立链接. 2) 不需要知道对方是否收到. 3) 数据不安全 4) 传输速度快 5)能支持并发 6) 不会粘包 7) 无需 ...

  3. UDP中的sendto 与recvfrom

    sendto 头文件: #include <sys/types.h>   #include <sys/socket.h> 定义函数: int sendto(int s, con ...

  4. 基于UDP协议的socket编程

    UDP协议特点: 1.无连接.服务端与客户端传输数据之前不需要进行连接,且没有超时重发等机制,只是把数据通过网络发送出去.也正是因为此特点,所以基于UDP协议的socket的客户端在启动之前不需要先启 ...

  5. 网络编程----socket介绍、基于tcp协议的套接字实现、基于udp协议的套接字实现

    一.客户端/服务器架构(C/S架构)                                                即C/S架构,包括: 1.硬件C/S架构(打印机) 2.软件C/S架 ...

  6. 网络编程基础之粘包现象与UDP协议

    一.粘包现象原理分析 1.我们先来看几行代码,从现象来分析: 测试程序分为两部分,分别是服务端和客户端 服务端.py #!/usr/bin/env python3 #-*- coding:utf-8 ...

  7. 网络编程基础:粘包现象、基于UDP协议的套接字

    粘包现象: 如上篇博客中最后的示例,客户端有个 phone.recv(2014) , 当服务端发送给客户端的数据大于1024个字节时, 多于1024的数据就会残留在管道中,下次客户端再给服务端发命令时 ...

  8. 基于UDP协议的socket套接字编程

    目录 一.UDP套接字简单示例 1.1 服务端 二.客户端 三.UPD套接字无粘包问题 3.1 服务端 3.2 客户端 四.qq聊天 4.1 服务端 4.2 客户端1 4.3 客户端2 4.4 运行结 ...

  9. 网络编程之基于UDP协议的套接字编程、基于socketserver实现并发的socket

    目录 基于UDP协议的套接字编程 UDP套接字简单示例 服务端 客户端 基于socketserver实现并发的socket 基于TCP协议 server类 request类 继承关系 服务端 客户端1 ...

随机推荐

  1. BUUCTF [SUCTF 2019]EasySQL

    首先打开网址 发现有三种显示方法 还有一个没有输出 可以堆叠注入 1;show databases; 1;show tables; 可以看到有一个Flag表 测试发现from flag都被过滤不能直接 ...

  2. FireFox浏览器的about:config参数大全及其具体用途介绍

    FireFox浏览器的about:config参数大全及其具体用途介绍,注意:这还远不是所有的about:config参数,由于设置参数太多,官方也只提供英文版本的说明,这里提供的FireFox ab ...

  3. jmeter 登陆--查询存在否-->新建客户-->查询存在否 + 压测

    1.登陆 正则表达式提取器和json提取器,都是后置处理器提取token(都可以在响应中以regexp tester 和 json path tester查看提取的对不对) beanshell 后置处 ...

  4. vue插槽(slot)的模板与JSX写法

    vue官网API: 插槽:https://cn.vuejs.org/v2/guide/components-slots.html JSX:https://cn.vuejs.org/v2/guide/r ...

  5. mysql获取字段信息

    SELECT TABLE_SCHEMA AS `databaseName`, TABLE_NAME AS `tableName`, COLUMN_NAME AS `columnName`, DATA_ ...

  6. PLSQL Developer12注册码

    product code: 4vkjwhfeh3ufnqnmpr9brvcuyujrx3n3le serial Number:226959 password: xs374ca 绝对靠谱

  7. 【资源分享】Gmod动态方框透视脚本

    *----------------------------------------------[下载区]----------------------------------------------* ...

  8. centos源码安装git最新版

    到 git官网下载git 源码安装包,git官网地址:https://www.git-scm.com/ 选择Tarballs系列的安装包,官网git下载:https://mirrors.edge.ke ...

  9. socket 异步I/O

    # 客服端 # -*- coding: utf-8 -*- import socket import threading # from collections import deque # q = d ...

  10. 【转载】C/C++编译过程分析

    转自:http://www.360doc.com/content/14/0109/16/835125_343879650.shtml C/C++编译过程 C/C++编译过程主要分为4个过程 1) 编译 ...