Linux UDP编程

版权声明:本文为博主原创文章,转载请备注https://blog.csdn.net/travelerwz。 https://blog.csdn.net/Travelerwz/article/details/82084468

## Linux UDP编程

udp是用户传输协议,无连接的传输协议,提供不可靠的信息传送服务

UDP(user datagram protocol)的中文叫用户数据报协议,属于传输层。UDP是面向非连接的协议,它不与对方建立连接,而是直接把我要发的数据报发给对方。所以UDP适用于一次传输数据量很少、对可靠性要求不高的或对实时性要求高的应用场景。正因为UDP无需建立类如三次握手的连接,而使得通信效率很高。

一张图来看看TCP和UDP的通信过程以及区别所在

这里写图片描述

我们来说一说UDP通信的过程:

服务端:

(1)建立套接字文件描述符,使用函数socket(),生成套接字文件描述符。

(2)设置服务器地址和侦听端口,初始化要绑定的网络地址结构。

(3)绑定侦听端口,使用bind()函数,将套接字文件描述符和一个地址类型变量进行绑定。

(4)接收客户端的数据,使用recvfrom()函数接收客户端的网络数据。

(5)向客户端发送数据,使用sendto()函数向服务器主机发送数据。

(6)关闭套接字,使用close()函数释放资源。UDP协议的客户端流程

客户端:

(1)建立套接字文件描述符,socket();

(2)设置服务器地址和端口,struct sockaddr;

(3)向服务器发送数据,sendto();

(4)接收服务器的数据,recvfrom();

(5)关闭套接字,close()。

常用UDP函数介绍

#include <sys/types.h>          
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
  • domain:我们一般就用对参数AF_INET和AF_INET6

  • type :

    SOCK_STREAM Provides sequenced, reliable, two-way, connection-based byte streams. //用于TCP

    SOCK_DGRAM Supports datagrams (connectionless, unreliable messages ). //用于UDP

    SOCK_RAW Provides raw network protocol access. //RAW类型,用于提供原始网络访问

  • protocol:置0即可

#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr* my_addr, socklen_t addrlen);
  • sockfd :正在监听端口的套接口文件描述符,通过socket获得
  • my_addr :绑定的IP和端口
  • addrlen :my_addr的结构体的大小 ,一般使用:sizeof(my_addr)
#include <unistd.h>
int close(int fd);
  • fd:socket产生的fd

UDP编程用到了两个函数,和我们前面TCP编程有一定的区别:

#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
              const struct sockaddr *dest_addr, socklen_t addrlen);
  • sockfd :正在监听端口的套接口文件描述符,通过socket获得

  • buf:发送缓冲区,自定义的数组,该数组装有要发送的数据

  • len:发送缓冲区的大小,单位是字节

  • flags:填0即可

  • dest_addr:指向接收数据的主机地址信息的结构体

  • addrlen:表示第五个参数所指向内容的长度

  • 返回值:成功:返回发送成功的数据长度;

    ​ 失败: -1

#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                struct sockaddr *src_addr, socklen_t *addrlen);
  • sockfd:正在监听端口的套接口文件描述符,通过socket获得

  • buf:接收缓冲区,往往是使用者定义的数组,该数组装有接收到的数据

  • len:接收缓冲区的大小,单位是字节

  • flags:填0即可

  • src_addr:指向发送数据的主机地址信息的结构体,也就是我们可以从该参数获取到数据是谁发出的

  • addrlen:表示第五个参数所指向内容的长度

  • 返回值:成功:返回接收成功的数据长度;

    ​ 失败: -1

程序实例:

util.h

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<netinet/in.h>

#define SERVER_PORT 8818
#define BUFFSIZE 1024

ser.c

#include"util.h"

int main()
{
    int rec,len;
    int timep;
    int sockfd;
    struct sockaddr_in server,client;
    char recvbuf[BUFFSIZE];
    char sendbuf[BUFFSIZE];

    sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd < 0)
        printf("sockfd error\n");
    bzero(&server,sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(SERVER_PORT);
    server.sin_addr.s_addr = htonl(INADDR_ANY);

    len = sizeof(struct sockaddr);
    if(bind(sockfd,(struct sockaddr*)&server,len)<0)
        printf("bind error\n");
    while(1)
    {
        rec = recvfrom(sockfd,recvbuf,BUFFSIZE,0,(struct sockaddr*)&client,&len);
        if(rec < 0)
            printf("recv error\n");
        printf("BUFFER:%s\n",recvbuf);
        timep = time(NULL);
        snprintf(sendbuf,sizeof(sendbuf),"%s",ctime(&timep));
        sendto(sockfd,sendbuf,sizeof(sendbuf),0,(struct sockaddr*)&client,len);

    }
    close(sockfd);
    return 0;
}

cli.c

#include"util.h"

int main()
{
    int rec,len;
    int timep;
    int sockfd;
    struct sockaddr_in server,client;
    char recvbuf[BUFFSIZE];
    char sendbuf[BUFFSIZE];

    sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd < 0)
        printf("sockfd error\n");
    bzero(&server,sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(SERVER_PORT);
    server.sin_addr.s_addr = htonl(INADDR_ANY);

    len = sizeof(struct sockaddr);
    if(bind(sockfd,(struct sockaddr*)&server,len)<0)
        printf("bind error\n");
    while(1)
    {
        rec = recvfrom(sockfd,recvbuf,BUFFSIZE,0,(struct sockaddr*)&client,&len);
        if(rec < 0)
            printf("recv error\n");
        printf("BUFFER:%s\n",recvbuf);
        timep = time(NULL);
        snprintf(sendbuf,sizeof(sendbuf),"%s",ctime(&timep));
        sendto(sockfd,sendbuf,sizeof(sendbuf),0,(struct sockaddr*)&client,len);

    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/Travelerwz/article/details/82084468