UDP通信

本文详细介绍了UDP通信的基础知识,包括IP与MAC地址、端口号、TCP与UDP的区别,以及网络字节序。接着,深入讲解了socket编程接口,涵盖服务端与客户端的创建、绑定、收发数据等关键步骤。最后,通过实例展示了如何制作一个简单的UDP多人网络聊天程序,实现了数据的双向传输。
摘要由CSDN通过智能技术生成

目录

一.预备知识

1.1IP与MAC

1.2端口号

1.3TCP与UDP协议

2.4网络字节序

二.socket编程接口

2.1socket常见API

2.2sockaddr结构

3.UDP网络程序

3.1服务端

3.1.1服务端创建套接字

3.1.2绑定服务端

3.1.3recvfrom

3.2客户端

3.2.1客户端创建套接字

3.2.2客户端绑定

3.2.3sendto

 3.3引入命令行参数

 3.4多人网络聊天制作

3.4.1客户端

3.4.2服务端

 3.5完整代码:



一.预备知识

1.1IP与MAC

IP地址,用来标识主机

源IP地址:发送方主机的IP地址

目的IP地址:接受方主机的IP地址

MAC地址,用来标识网卡

源MAC地址:发送方主机的MAC

目的MAC地址:接收方主机的MAC

补充:数据基本都是跨局域网传送的,网络层封装的报头当中有IP与MAC,IP地址是不会改变的。

但数据跨网络到达另一个局域网时,其源MAC地址和目的MAC地址就会发生变化。

1.2端口号

作用:用来标识一台计算机中的一个进程。

介绍下socket通信:

通过IP与MAC可找到公网上的唯一主机,通过端口号可找到那台主机上的对应的进程

通过IP与MAC已经可以完成数据的传输了,但本质其实是两台计算机的进程在进行通信,是跨网络的,而端口号就是来标识计算机中的进程,也分为源端口号,目的端口号。

  • 源端口号: 发送方主机的服务进程绑定的端口号,保证接收方能够找到对应的服务
  • 目的端口号 接收方主机的服务进程绑定的端口号,保证发送方能够找到对应的服务

补充内容:

1.端口号是传输层协议的内容。 

2.进程间的通信有共享内存,消息队列等,以及套接字(跨网络)

3.一个端口号只能被一个进程占用。一个进程可以绑定多个端口号,但是一个端口号不能被多个进程同时绑定。

4.进程ID(PID)是用来标识系统内所有进程的唯一性的,它是属于系统级的概念;而端口号(port)是用来标识需要对外进行网络数据请求的进程的唯一性的,它是属于网络的概念。

  底层可采用哈希的方式,建立了端口号和进程PID或PCB之间的映射关系

1.3TCP与UDP协议

TCP:要进行数据传输,二者要先进行连接

  • 传输层协议
  • 有连接的
  • 可靠传输
  • 面向字节流

UDP:进行数据传输时,不需要进行连接,发送数据即可,但无法确定数据的可靠性

  • 传输层协议
  • 无连接
  • 不可靠传输
  • 面向数据报

2.4网络字节序

大小端介绍

           大端:高位存放在低地址,低位存放在高地址

           小端:低位存放在低地址,高位存放在高地址

巧计:低低是小端

 网络上的字节流内存一样,也有大小端之分。

TCP/IP协议规定,网络数据流采用大端字节序,不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序来发送/接收数据。(发送数据时按内存地址从低到高的顺序发出,接受数据时是按内存地址从低到高的顺序保存)

 使网络程序具有可移植性,调用以下库函数实现网络字节序和主机字节序之间的转换

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
  • h代表的是host,n代表的是network,s代表的是16位的短整型,l代表的是32位长整形
  • 如果主机是小端字节序,函数会对参数进行处理,进行大小端转换
  • 如果主机是大端字节序,函数不会对这些参数处理,直接返回

二.socket编程接口

2.1socket常见API

创建套接字:(TCP/UDP,客户端+服务器)

int socket(int domain, int type, int protocol);

绑定端口号:(TCP/UDP,服务器)

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

监听套接字socket :(TCP,服务器)

int listen(int sockfd, int backlog);

接收请求:(TCP,服务器)

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

建立连接:(TCP,客户端)

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

2.2sockaddr结构

在这里插入图片描述

其中struct sockaddr_in是用于网络通信,struct sockaddr_un是用于本地通信。sockaddr_in结构体存储了协议家族,端口号,IP等信息,网络通信时可以通过这个结构体把自己的信息发送给对方,也可以通过这个结构体获取对端的这些信息。

为了能让套接字的网络通信和本地通信能够使用同一套函数接口,于是出现了sockeaddr结构体。其中这三个结构体的头部前16位是一样的,这个字段叫做协议家族。所以在用这个函数时可以统一传入sockeadder结构体,在设置参数时就可以通过设置协议家族这个字段,来表明我们是要进行网络通信还是本地通信。
 

补充内容:

1.IPv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位地址类型,16位端口号和32位IP地址。
2.IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6。这样,只要取得某种sockaddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容。
3.socket API可以都用struct sockaddr* 类型表示,在使用的时候需要强制转化成sockaddr_in;这样的好处是程序的通用性,可以接收IPv4、IPv6,以及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数。

3.UDP网络程序

介绍:制作一个server服务端,用来提供各种服务。制作一个client客户端,可向服务端发送请求,服务端接受数据并处理后,再将数据返回给客户端。都将二者进行封装为一个类。

3.1服务端

3.1.1服务端创建套接字

创建套接字函数:

int socket(int domain, int type, int protocol);

参数解释:

domain:创建套接字的域或者叫做协议家族,也就是创建套接字的类型。该参数就相当于struct sockadd

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值