IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 第8章 UDP套接字编程 -> 正文阅读

[网络协议]第8章 UDP套接字编程

一、概述

使用UDP编写的一些常见的应用程序有:DNS(域名系统)、NFS(网络文件系统)和SNMP(简单网络管理协议)。
在这里插入图片描述

二、recvfrom和sendto函数

这两个函数类似于标准的read和write函数,不过需要三个额外的参数

#include <sys/socket.h>

ssize_t recvfrom(int sockfd, void* buff, size_t nbytes, int flags, struct sockaddr* from, socklen_t* addrlen);
ssize_t sendto(int sockfd, const void* buff, size_t nbytes, int flags, const struct sockaddr* to, socklen_t addrlen);
  • 前三个参数,等同于read和write的三个参数,描述符、读写缓冲区指针、读写字节数
  • flags14章介绍,当前总是设置为0
  • recvfrom的from参数存放发送者的套接字地址结构,由函数返回时填写;sendto的to参数指向一个数据报接受者的协议地址的套接字结构。
  • recvfrom的addrlen是指针,同样由函数返回给调用者;sendto中的addrlen是整数,指定地址结构的大小

recvfrom返回0是可以接受的,不像read返回0表示对端关闭连接。因为UDP是无连接的,也就没有所谓的关闭。

三、UDP回射服务器和客户端程序

在这里插入图片描述

3.1 服务端程序

#include "unp.h"

void dg_echo(int sockfd, SA* pcliaddr, socklen_t clilen)
{
	int 	n;
	socklen_t len;
	char    mesg[MAXLINE];
	while(1){
		len = clilen;
		n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
		Sendto(sockfd, mesg, n, 0, pcliaddr, len);
	}
}

int main(int argc, char** argv)
{
    int	   sockfd;
    struct sockaddr_in cliaddr, servaddr;

    sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
    
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERV_PORT);
    
    Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));
    
	dg_echo(sockfd, (SA*)&cliaddr, sizeof(cliaddr));
}

关于dg_echo函数的细节:

首先,该函数永不终止,因为UDP是无连接的,没有EOF之类的东西;大多数TCP服务器是并发的,大多数UDP服务器是迭代的。
对于本套接字,UDP层中隐含有排队发生。每个UDP套接字都有一个接收缓冲区,缓冲区中的数据通过FIFO顺序返回给进程。与TCP服务器不同的是,TCP服务器有多个子进程,每个已连接套接字都有各自的接收缓冲区;而此UDP服务器仅有一个服务器进程,仅有单个套接字用于接收所有到达的数据报并发回所有响应。

3.2 客户端程序

#include "unp.h"

void dg_cli(FILE* fp, int sockfd, const SA* pservaddr, socklen_t servlen)
{
	int n;
	char sendline[MAXLINE], recvline[MAXLINE + 1];
	//fgets在读取了n-1个字符、读到了'\n'或遇到了EOF三种情况之一时都结束读取。并在之后加'\0'结束符
	while(Fgets(sendline, MAXLINE, fp) != NULL){
		Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, socklen_t);
		n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
		recvline[n] = 0;
		Fputs(recvline, stdout);
	}	
}

int main(int argc, char** argv)
{
    int sockfd;
    struct sockaddr_in servaddr;

    if(argc != 2)
        err_quit("usage: udpcli <IPadress>");

    sockfd = Socket(AF_INET, SOCK_DGRAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERV_PORT);
    Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

	dg_cli(stdin, sockfd, (SA*)&servaddr, sizeof(servaddr));
	
    exit(0);
}

客户端的recvfrom中第五和第六参数都是空指针,这告知内核我们不关心是谁发送的数据报。这样做的风险是任何进程都可以向本客户的IP和端口发送数据报,而被客户读入并误以为是服务器的回应。

四、UDP服务器程序的面临的各种情况

4.1 数据报的丢失

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-11-25 08:28:41  更:2021-11-25 08:28:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:23:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码