当前位置:   article > 正文

[linux C]UDP服务器、客户端程序实现(本地)_linux c udp

linux c udp

1、UDP简介

UDP(User Datagram Protocol)用户数据报协议是一种非面向连接的协议,这种协议并不能保证
我们的网络程序的连接是可靠的,而TCP是面向连接的协议,提供可靠服务。但是相对于TCP而言,UDP实时性较好,适用于高速传输和实时性要求较高的通信中。

2、实现过程

UDP服务器端实现步骤:
1、创建socket,选用SOCK_DGRAM(UDP)
2、bind绑定ip地址和socket
3、使用recvfrom()函数接收客户端数据
(4、使用sendto函数发送数据)
UDP客户端实现步骤:
1、创建socket,选用SOCK_DGRAM(UDP)
2、定义sockaddr_in 结构体变量并初始化
3、使用recvfrom()函数接收客户端数据
相关函数API介绍

int socket(int domain, int type, int protocol);
参数:
	domain:域。
	AF_INET/PF_INET: 网际协议
	AF_UNIX/PF_UNIX:本地协议,可写成AF_LOCAL/PF_LOCAL
	type:类型
		SOCK_STREAM:流式套接字
		SOCK_DGRAM:数据报套接字
	protocol:协议
		一般为0
返回值:
	成功:待连接套接字; 
	失败:-1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数:
	sockfd:待连接套接字
	addr:包含本地地址(IP+PORT)的通用地址结构体的指针
	addrlen:地址结构体大小
返回值:
	成功:0;
	失败:-1
备注,通用地址结构体的定义:
struct sockaddr
{
	sa_family_t  sa_family;
	char         sa_data[14];
};

特殊地址结构体 —— IPv4地址结构体:
struct sockaddr_in
{
    u_short sin_family;	// 地址族
    u_short sin_port;	// 端口
    struct in_addr sin_addr;	// IPV4地址
    char sin_zero[8];
};
struct in_addr
{
	in_addr_t s_addr;	// 无符号32位网络地址
};

特殊地址结构体 —— IPv6地址结构体:
struct sockaddr_in6
{
	u_short sin6_family;    	// 地址族
	__be16 sin6_port;     		// 端口
	__be32 sin6_flowinfo;		// 流信息
	struct in6_addr sin6_addr;  // IPv6地址
	__u32 sin6_scope_id;
};

特殊地址结构体 ——UNIX域地址结构体:
struct sockaddr_un
{           
	u_short sun_family;	// 地址族
	char sun_path[108];	// 套接字文件路径
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);
接口声明:从UDP套接字接收数据
参数:
	sockfd:UDP套接字
	buf:储存数据缓冲区
	len:缓冲区大小
	flags:接收标志,与函数send的flags完全一致
	src_addr:对端网络地址
	addrlen:地址长度
返回值:
	成功:已接收字节数
	失败:-1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.1服务器代码

/*
    基于UDP实现的服务器
author:zx
date:2023-3-10
创建服务步骤:
    1、创建socket,选用SOCK_DGRAM(UDP)
    2、bind绑定ip地址和socket
    3、使用recvfrom()函数接收客户端数据
*/
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
int main()
{
    int sockfd;
    int retval;
    if(sockfd == -1)
    {
        printf("sock error\n");
        return -1;
    }
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr =htonl(INADDR_ANY);//任意地址
    serverAddr.sin_port = htons(6565);
    retval = bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
    if(retval < 0)
    {
        printf("bind error\n");
        return -1;
    }
        {
            printf("[UDP server]recv form client:%s\n", buf);
        }
        else
        {
            printf("[UDP server] recv error!\n");
            break;
		}
    }
    close(sockfd);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

2.2客户端代码

/*
    基于UDP实现的客户端
author:zx
date:2023-3-10



创建服务步骤:
    1、创建socket,选用SOCK_DGRAM(UDP)
    2、定义sockaddr_in 结构体变量并初始化
    3、使用recvfrom()函数接收客户端数据
*/

#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
int main()
{
    int sockfd;
    int retval;
    struct sockaddr_in clientAddr;
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);//UDP   
    if(sockfd == -1)
    {
        printf("sock error\n");
        return -1;
    }
    clientAddr.sin_family = AF_INET;
    clientAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    clientAddr.sin_port = htons(6565);
    char buf[1024] = "hello udp server";
    socklen_t len = sizeof(clientAddr);
    int count = 0;
    while(1)
    {
        sprintf(buf, "hello udp server,count:%d", count++);
        retval = sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&clientAddr, len);
        if(retval > 0)
        {
            printf("[UDP client]send to server:%s\n", buf);
        }
        else
        {
            printf("[UDP client] send error!\n");
            break;
        }
        sleep(2);
    }
    close(sockfd);
    return 0;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

3、运行结果

客户端
在这里插入图片描述
服务器端
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/179972
推荐阅读
相关标签
  

闽ICP备14008679号