如何用UDP协议搭建一个可以进行网络通信的网络环境

本文介绍了如何利用UDP协议进行网络通信。首先讲解了网络字节序的重要性,然后阐述了IP和PORT在定位网络进程中的作用。接着,讨论了UDP协议的非连接特性,并详细说明了从创建文件描述符到绑定IP+PORT,再到服务器和客户端通信的步骤。最后,给出了服务器和客户端的代码框架,为实际应用提供指导。
摘要由CSDN通过智能技术生成

准备工作

网络字节序

由于每一台主机的大小端都有可能是不一样的,我们在主机内部进行通信的时候,不会有大小端不同的问题,而在进行跨主机进行通信的时候,就会出现两台主机的字节序不同,为了统一标准,在网络中通信的数据,统一采用大端的存储方式。如果机器是大端,在发送的时候,不做任何修改,如果主机是小端的字节序,则在发送的时候,需要先将数据转化为大端,然后再发送。
为了便于我们直接通过调用一些已经写好的接口直接能完成网络字节序的装换,系统为我们提供了以下的一些接口

uint32_t htonl(uint32_t hostlong); //主机转网络
uint16_t htons(uint16_t hostshort); //主机转网络
uint32_t ntohl(uint32_t hostlong); //网络转主机
uint16_t ntohs(uint16_t hostshort); //网络转主机

以上的,就是网络字节序的转化

IP + PORT

在网络通信的过程中,IP唯一标识网络中的一台主机,而PORT,也就是端口号,唯一标识一台主机上的唯一的一个进行网络通信的进程。通过IP寻找主机,再通过端口号,寻找该主机上的一个进程,就保证了传输的准确性。
复杂的网络环境,其实可以看做是一台超级巨大的主机,只不过这台主机进行进程间通信的时候,是通过网络环境进行的。

socket的一些接口以及这些接口中数据类型的详细信息

常见的API接口

int socket(int domain,int type,int protocol);
//这个接口的作用是创建一个socket文件描述符,然后将其返回

int bind(int socket,const struct sockaddr* address,socklen_t address_len);
//这个接口的作用是 将你先前创建的socket文件描述符与你后来创建的sockaddr_in类型的变量进行绑定
//(先将端口号和ip在sockaddr_in类型的变量中填充,再进行绑定),创建好网络通信的环境。
// 该接口的作用就是,利用本地的一个socket类型的文件描述符,和一个sockaddr_in类型(里面含有ip和端口号)的变量,
//实现对文件描述符的读写操作,等同于网络间的收发信息。

UDP传输协议

UDP是什么

UDP协议是网络中两个主机进行通信的时候,所采用的的一种非连接的通信协议,核心数非连接。(非连接的意思是:接受方与发送方并不建立连接,接收方不看给他发送信息的发送者是谁,只是一味地接收,发送方也不看接收方是谁,只是一味地发送) 。面向的是数据报。不可靠的一种传输方式。

如何进行搭建

1.文件描述符创建

刚才说了,网络间通信可以看做是进程间进行通信的一种特殊形式,既然是进程间通信,就必须有一个公共区域,也就是一个文件,对这个文件进行操作的话,就必须有文件描述符。我们第一步的操作就是,创建文件描述符,并检验他的正确性。

int sockfd = socket(AF_INET,SOCK_DGRAM,0);\
// 用socket调用,创建用于网络间通信的文件描述符。
//socket函数的第一个参数是 通信协议类型 AF_INET是ipv4协议家族。
//第二个参数是通信方式,因为这里是UDP协议的通信方式,所以是SOCK_DGRAM,无连接的通信方式。
//最后一个参数是接收方通信协议地选择,我们这里用0,表示自动选择。
if(sockfd < 0)
{
   
    exit(2);
}

2.将文件描述符进行绑定

我们进行网络间通信的最重要的是先要找到对方,而我们找到对方的方式就是通过IP+PORT进行寻找的,我们已经创建好了文件描述符,接下来就是要对文件描述符与IP+PORT进行绑定的过程
sockaddr_in 类型和sockaddr类型,在物理存储上是一样的,只是表示方式不同,我们在使用的时候,需要将sockaddr_in类型强制类型转换为sockaddr类型的。
bind函数如果成功,返回值就是0,如果不成功,就返回错误码。

string ip;
short port;

struct sockaddr_in local;
bzeor(&local,sizeof(local));
//对结构体进行清空

local.sin_family = AF_INET;
//填充协议家族
local.sin_addr.s_addr = inet_addr(ip);
//填充IP地址,需要将字符串类型转化为十进制,
//用inet_addr接口,可以直接完成转换
local.sin_port = htons(port);
//填充端口号,也是需要转换,将short类型主机转网络,
//也就是开始说的网络字节序的转换。
if( bind(sockfd, (struct sockaddr*)&local, sizeof(local) ) == 0)
{
   
    // true
    // ...
}
else
{
   
    // false
    exit(3);
}

3.开始网络间通信

网络间通信,至少有两个角色,一个是服务器,一个是客户端。既然如此,就需要服务器和客户端完成各自的任务。
服务器:服务器需要接收客户端发来的请求,并作出回应。
客户端:想服务器提出请求,并接收服务器的返回

服务器框架(这里只完成了服务器的接收操作,

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值