网络编程基础-UDP为例

本文介绍了网络编程基础,主要围绕UDP协议展开,包括IP地址、端口号、套接字和网络字节序的概念。通过实例展示了如何创建简单的UDP回显服务器和客户端,并详细解析了涉及的网络编程函数,如socket、shutdown、bind、sendto和recvfrom等。
摘要由CSDN通过智能技术生成

个人博客传送门

本文只是基于认识的讲述网络编程基础。

基础认识

认识IP
  • IP地址是在IP协议中用来表示网络中不同的主机的地址
  • IPv4是4个字节,32位;IPv6是16个字节,128位。目前通用的是IPv4。
  • 通常用点分十进制来的字符串来表示IP地址。例如常见的192.168.1.1,每一个点分隔一个字节,范围是0~255

理解源IP地址和目的IP地址:源IP地址是发送端的IP地址,目的IP地址是接收端的IP地址。这两个地址指明了数据的来源主机和目的主机。

认识端口号

端口号是传输层协议需要的数据。

  • 端口号是一个2字节的整数,16位。
  • 端口号用来唯一标识一个网络进程,它可以告诉OS这些数据需要提交给哪一个进程来处理。
  • 一个端口号只能被一个进程占用。

我们的数据在网络中传输,通过IP地址,我们可以找到目的主机。但是很遗憾,在目的主机上处理数据的个体是进程。所以我们需要端口号来表示主机中的进程。这样我们的数据才可以准确的交付给网络中的唯一主机上的唯一进程。所以一个进程可以绑定多个端口号,但是一个端口号只能被一个一个进程绑定。

认识套接字

套接字叫做socket,是一个由IP和端口号组成的结构。通过他,我们可以在网络上找到唯一的主机上的唯一进程,他是网络传输中的基本入口。在Linux的一切皆文件的思想下,我们在网络中创建了连接,通过打开的socket表示,同时socket用文件描述符描述起来。

认识网络字节序

网络字节序指的是多字节的数据在网络中的排序。比如一个整型数据有四个字节,他的字节次序有两种,一种是低字节数据放在低地址处,这个叫做小端;另一种是低字节数据放在高地址处,这个叫做大端。

通常我们的主机的字节序是不确定的。有可能出现一个小端的主机将数据发送给大端的主机。这样就需要一种规范,我们规定在网络中的的字节序是按照大端的。这样如果发送端是小端机,发送数据的时候就需要将字节序转换过来,如果是大端机就不需要做处理。这就就可以避免大小端带来的数据错误。

#include <arpa/inet.h>

//将32位长整型主机字节序转换为网络字节序
uint32_t htonl(uint32_t hostlong);
//将16位短整型主机字节序转换为网络字节序
uint16_t htons(uint16_t hostshort);
//将32位长整型网络字节序转换为主机字节序
uint32_t ntohl(uint32_t netlong);
//将16位短整型网络字节序转换为主机字节序
uint16_t ntohs(uint16_t netshort);

上述函数就是用来转换字节序的。我们默认32位用于IPv4的转换,16位用于端口号的转换。如果主机是小端机,那么函数会将小端字节序转换为大端字节序;如果是大端机,函数不会有任何作用。

简单的UDP回显服务器和客户端程序

部分使用函数
//用于创建socket接口,返回一个文件描述符。
int socket(int domain, int type, int protocol);
//用于将socket_fd和端口进行绑定。
int bind(int socket, const struct sockaddr* address, socklen_t address_len);
//用于UDP这类无连接的数据发送。
ssize_t sendto(int sockfd, const void* buf, size_t nbytes, int flags, const struct sockaddr* destaddr, socklent_t destlen);
//用于UDP这类无连接的数据接收。
ssize_t recvfrom(int sockfd, void* restrict buf, size_t len, int flags, struct sockaddr* addr, socklent_t *addrlen);
参数类型sockaddr结构解析

观察上面的函数,会看到一个参数的类型为struct sokaddr*。这个参数是网络编程函数中为了实现类似于void*泛型功能而产生的。(一个地址标识一个特定的通信域的套接字端点,地址格式与这个特定的通信域相关。为了让不同格式地址能够传入到套接字函数中,地址会被强转为一个通用的地址结构sockaddr)

在Linux中,sockaddr被定义为:

struct sockaddr{
    sa_family_t sa_family;
    char        sa_data[14];
};

sa_family指的是地址类型。

因特网地址定义在

struct sockaddr_in{
    sa_family_t sin_family;
    in_port_t sin_port;
    struct in_addr sin_addr;
};

struct in_addr{
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值