Linux之UDP协议及其编程全流程

目录
  • UDP协议的特点
  • UDP的编程流程
  • UDP接口原型
    • UDP服务器端
    • UDP客户端
  • UDP的报头结构
  • UDP的优势
  • UDP的数据报服务
  • 总结

UDP协议的特点

UDP 不提供可靠性的传输,它只是把应用程序传给 IP 层的数据报发送出去,但是并不能保证它们能到达目的地。

由于 UDP 在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

  • 无连接
  • 不可靠
  • 数据报服务

UDP发出的数据包不经过确认,可以继续发送。发送成功与否都不管,尽最大能力去发送,丢包也不负责。有自己的使用特点:适合于做视频(实时性)适合于即使丢包了,处理起来也比较方便。

适合于摄像头以恒定速率发,对方以恒定速率收,丢包了继续发,可以实时。

但是如果是TCP,如果丢包,会重发,时间花销大了,不能实时。不适合做摄像头和视频。

UDP的编程流程

UDP接口原型

接收

int recvfrom(int sockfd,void *buf,size_t size,int flag,struct sockaddr *peer_addr,socklen_t *addr_len);
  • peer_addr:用来保存recvfrom接收到的数据是来自哪台主机的地址信息
  • addr_len:地址结构的长度

发送

int sendto(int sockfd,void *buf,size_t size,int flag,struct sockaddr *peer_addr,socklen_t addr_len);
  • peer_addr:用来指定数据的接收方的地址信息
  • addr_len:地址信息的长度

示例代码

UDP服务器端

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<unistd.h>

#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<netinet/in.h>

int main()
{
    //SOCK_DGRAM表示使用的是UDP协议
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    assert(sockfd != -1);

    struct sockaddr_in ser_addr;
    memset(&ser_addr,0,sizeof(ser_addr));
    ser_addr.sin_family = AF_INET;
    //将主机字节序转化为网络字节序
    ser_addr.sin_port = htons(6000);
    //将点分十进制的地址字符串转为unit32类型的值
    ser_addr.sin_addr.s_addr = inet_addr("192.168.246.128");

    int res = bind(sockfd,(struct sockaddr*)&ser_addr,sizeof(ser_addr));
    assert(res != -1);

    //循环接受不同客户端的数据
    while(1)
    {
        char buff[128] = {0};

        struct sockaddr_in cli_addr;
        socklen_t cli_len = sizeof(cli_addr);
        int n = recvfrom(sockfd,buff,127,0,(struct sockaddr*)&cli_addr,&cli_len);
        if(n <= 0)
        {
            break;
        }

        printf("%s:%d -- %s\n",inet_ntoa(cli_addr.sin_addr),ntohs(cli_addr.sin_port),buff);   

        n = sendto(sockfd,"OK",2,0,(struct sockaddr*)&cli_addr,cli_len);
        if(n <= 0)
        {
            break;
        }
    }

    close(sockfd);
    exit(0);
}

UDP客户端

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<unistd.h>

#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<netinet/in.h>

int main()
{
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    assert(sockfd != -1);

    struct sockaddr_in ser_addr;
    memset(&ser_addr,0,sizeof(ser_addr));
    ser_addr.sin_family = AF_INET;
    ser_addr.sin_port = htons(6000);
    ser_addr.sin_addr.s_addr = inet_addr("192.168.246.128");

    while(1)
    {
        printf("请输入:");
        char buff[128] = {0};
        fgets(buff,127,stdin);

        if(strncmp(buff,"end",3) == 0)
        {
            break;
        }

        int n = sendto(sockfd,buff,strlen(buff),0,(struct sockaddr*)&ser_addr,sizeof(ser_addr));
        if(n <= 0)
        {
            break;
        }

        memset(buff,0,128);

        int m = recvfrom(sockfd,buff,127,0,NULL,NULL);//服务器地址信息已知,无需保存直接传入NULL
        if(m <= 0)
        {
            break;
        }
        printf("%s\n",buff);
    }   

    close(sockfd); 

    exit(0);
}

两个客户端同时向服务器端发送信息

多个客户端可以和服务器一起链接通讯。recvfrom并不是只等第一个或者第二个客户端,而是谁给它发,它就收谁的。

如果在客户端保持运行状态的情况下,将服务器端关闭,然后再把服务器端重新运行起来,这时候客户端发送数据,服务器端是可以收到的。

因为UDP本来就没有建立连接。如果服务器端关了,客户端send就失败了。 数据包丢了就丢了,不会理会。不管关闭哪一端,对方端都不知道这件事情,彼此无关系,无影响。

如果让服务器端一次只接受一个字符,我给你发一个数据包,你去收这个数据包,你recvfrom,你把这个数据包拆开,你读取1个字符,后面的不读,直接就丢掉了。

UDP的报头结构

UDP的报头固定是8个字节!

  • UDP的报文段长度 – 表示这个UDP报文段的报头+数据部分的总长度 一个UDP报文段数据部分的长度为总长度 - 8
  • 冗余检验码 – 会对整个UDP数据报进行冗余校验

UDP的优势

  • 没有确认机制和超时重传机制,发送方发送报文段的效率就很高。
  • 头部固定部分比较小,一个UDP报文段所携带的上次协议的数据就比TCP多一点。
  • UDP的实现相对比较简单。

UDP的数据报服务

  • sendto和recvfrom的次数是一一对应的。
  • sendto一次,底层就发送一个UDP报文段,对方就接受这一个UDP报文段。
  • 如果一次recvfrom没有将一个UDP报文段中的数据读取完成,则剩余的数据会被丢弃。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Linux Socket编程(不限Linux)

    我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用QQ聊天时,QQ进程怎么与服务器或你好友所在的QQ进程通信?这些都得靠socket?那什么是socket?socket的类型有哪些?还有socket的基本函数,这些都是本文想介绍的.本文的主要内容如下: 1.网络中进程之间如何通信? 本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类: 消息传递(管道.FIFO.消息队列) 同步(互斥量.条件变量.读写锁.文件和

  • Linux UDP socket 设置为的非阻塞模式与阻塞模式区别

    Linux UDP socket 设置为的非阻塞模式与阻塞模式区别 UDP socket 设置为的非阻塞模式 Len = recvfrom(SocketFD, szRecvBuf, sizeof(szRecvBuf), MSG_DONTWAIT, (struct sockaddr *)&SockAddr,&ScokAddrLen); UDP socket 设置为的阻塞模式 Len = recvfrom(SocketFD, szRecvBuf, sizeof(szRecvBuf), 0, (

  • Linux编程之PING实现

    PING(Packet InterNet Groper)中文名为因特网包探索器,是用来查看网络上另一个主机系统的网络连接是否正常的一个工具.ping命令的工作原理是:向网络上的另一个主机系统发送ICMP报文,如果指定系统得到了报文,它将把回复报文传回给发送者,这有点象潜水艇声纳系统中使用的发声装置.所以,我们想知道我这台主机能不能和另一台进行通信,我们首先需要确认的是我们两台主机间的网络是不是通的,也就是我说的话能不能传到你那里,这是双方进行通信的前提.在Linux下使用指令ping的方法和现象

  • Linux之UDP协议及其编程全流程

    目录 UDP协议的特点 UDP的编程流程 UDP接口原型 UDP服务器端 UDP客户端 UDP的报头结构 UDP的优势 UDP的数据报服务 总结 UDP协议的特点 UDP 不提供可靠性的传输,它只是把应用程序传给 IP 层的数据报发送出去,但是并不能保证它们能到达目的地. 由于 UDP 在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快. 无连接 不可靠 数据报服务 UDP发出的数据包不经过确认,可以继续发送.发送成功与否都不管,尽最大能力去发送,丢包也不负

  • java实现基于UDP协议网络Socket编程(C/S通信)

    一.前言:认识UDP UDP,全称User Datagram Protocol(用户数据报协议),是Internet 协议集支持一个无连接的传输协议.UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法. UDP主要用于不要求分组顺序到达的传输中,分组传输顺序的检查与排序由应用层完成,提供面向报文的简单不可靠信息传送服务.UDP 协议基本上是IP协议与上层协议的接口,适用端口分别运行在同一台设备上的多个应用程序. 二.UDP的特点(与TCP相比) 正是UDP提供不可靠服务

  • 关于UDP服务器客户端编程流程介绍

    目录 UDP编程流程 UDP服务端代码实现 UDP客户端代码实现 UDP服务端客户端代码详解 UDP编程流程 UDP提供的是无连接.不可靠的.数据报服务 UDP是尽最大能力进行传输,但是并不能保证可靠性,TCP的可靠性是因为一系列的机制保证可靠性,UDP丢包并不会重发,两种协议并没有优略之分,要区分不同的场景来区分,比如:进行文件传输,不能有数据丢失,TCP协议就更合 适,而进行实时视频通话,UDP会根据恒定的速率进行发送,这样的情况容许部分数据的丢失去追求更好的实时性,所以UDP更合适 流程:

  • Linux中使用C语言实现基于UDP协议的Socket通信示例

    linux下udp服务器端源码示例: #include <errno.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> #include <netinet/in.h> #include <stdio.h> #include <un

  • 解析C语言基于UDP协议进行Socket编程的要点

    两种协议 TCP 和 UDP 前者可以理解为有保证的连接,后者是追求快速的连接. 当然最后一点有些 太过绝对 ,但是现在不需熬考虑太多,因为初入套接字编程,一切从简. 稍微试想便能够大致理解, TCP 追求的是可靠的传输数据, UDP 追求的则是快速的传输数据. 前者有繁琐的连接过程,后者则是根本不建立可靠连接(不是绝对),只是将数据发送而不考虑是否到达. 以下例子以 *nix 平台的便准为例,因为 Windows平台需要考虑额外的加载问题,稍作添加就能在 Windows 平台上运行UDP. U

  • java编程实现基于UDP协议传输数据的方法

    本文实例讲述了java编程实现基于UDP协议传输数据的方法.分享给大家供大家参考,具体如下: UDP协议(User Datagram Protocol,用户数据报协议)不同于TCP协议,它是不可能靠的,但是它比TCP协议具有更快的传输速度,UDP发送的数据单元称为数据报,当网络传输UDP传输UDP数据报是无法保证数据能够到达目的地,也无法保证按发送的顺序到达目的地,也就是说先发送了"hello",再发送了"world",但接收方可能会先收到"world&q

  • Java网络编程UDP协议发送接收数据

    本文实例为大家分享了Java网络编程UDP协议发送接收数据的具体代码,供大家参考,具体内容如下 UDP协议发送数据步骤 A:创建发送端socket对象: B:创建数据,并把数据打包: C:调用socket对象的发送方法发送数据包: D:释放资源 package net; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAd

  • 深入理解TCP协议与UDP协议的原理及区别

    网络编程有三个要素,分别是IP地址.端口号和通信协议,那本文主要讲述的是TCP与UDP这两种通信协议,以及编程的实现. 首先,我们需要了解一下IP地址.端口号.通信协议的相关知识. 一.IP地址 网络中的计算机使用IP地址来进行唯一标识,IP地址有IPv4和IPv6两种类型.IPv4采用十进制或二进制表示形式,十进制是一种比较常用的表示形式,如192.168.1.131,IPv6采用十六进制表示形式,一般不常用. 如何查看IP地址相关信息: 在Windows系统下,打开cmd,输入命令ipcon

  • linux对于UDP的学习

    目录 一.UDP.linux基础介绍 二.对于各函数使用 1.对于socket函数的使用 2. 对于bind函数的使用 3. 对于recvfrom函数的使用 4. 对于sendto函数的使用 三. 扩展知识 1. netstat 2. pidof 一.UDP.linux基础介绍 套接字:就是IP地址+端口号 IP地址:4字节 端口号:2字节,也就是说范围是0~65535 端口号分为:知名端口号.一些固定的端口号 知名端口号 0--1023:http,ssh,ftp,telnet等一些协议端口号都

  • MySQL五步走JDBC编程全解读

    目录 一.数据库编程的必备条件 二.Java的数据库编程:JDBC 三.JDBC工作原理 四.开发环境搭建 五.MySQL中的JDBC编程 1.五步流程 2.添加信息 3.查询信息 4.删除信息 5.修改信息 一.数据库编程的必备条件 编程语言,如Java,C.C++.Python等 数据库,如Oracle,MySQL,SQL Server等 数据库驱动包:不同的数据库,对应不同的编程语言提供了不同的数据库驱动包,如:MySQL提 供了Java的驱动包mysql-connector-java,需

随机推荐