前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >【Linux网络】————socket和udp协议

【Linux网络】————socket和udp协议

作者头像
用户11036582
发布2024-12-18 16:56:00
发布2024-12-18 16:56:00
13700
代码可运行
举报
运行总次数:0
代码可运行

一、六个背景知识

1、在进行网络通信时,是不是两台电脑在通信?

答案:当然不是这样的,事实上是应用层在通信 解析:网络协议中的下三层,主要是解决的是将数据安全可靠的送到远端机器,用户使用应用层软件实现数据的发送和接收。而在使用软件的时候,必须要先启动这个软件,例如我们现在要使用微信,运行之后这个就是进程。所以网络在进行通信的时候就是进程间通信!!!只不过是进程之间遵守了网络协议栈,用的是网络协议的系统调用接口罢了,但是其本质还是进程间通信!!!手段是两台主机通信。而目的和本质是进程之间的通信,是凌驾于应用层上的进程间通信。通过网络协议栈来读取网络资源(共享内存资源)来让两台主机读取/存放信息。可以用读者/写者问题来理解这个问题,我们的网络资源就对应着缓冲区这个概念,读者写者在这个缓冲区(网络资源)中读取和存放资源。

2、端口号:

端口号是一个两字节十六位的整数 端口号用来标识一个进程,告诉操作系统,当前的数据要交给哪个进程来处理 我们上一篇文章说过,IP是独一无二的,每个主机只有一个IP,所以IP地址+端口号就可以描述一个独一无二的进程。一个端口号只能被一个进程所占用。

特别注意的概念:

在公网上,ip值能标识唯一的一台主机,port端口号能标识该主机上唯一的一个进程。如ip:port能标识全网唯一一个进程。 socket:客户端和服务器在进行通信的时候,客户端拥有唯一的ip值加端口号,服务端进程也有唯一的ip值+端口号,所以客户端和服务端只需要记住对方的源和目的的IP值+端口号就就可以进行两者之间的通信。这就是socket

3、端口号vs进程PID

我们之前在讲进程的时候说过,一个进程有唯一的pid,既然pid已经能够标识一台主机上的一个进程的唯一性,那为什么还要有端口号这个概念呢? 答案:引入端口号是为了实现系统和网络之间的解耦合,以免后期造成其他不必要的影响

4、目的端口怎么跟客户端绑定的呢?也就是怎么通过目的端口去找到对应的进程的呢?

5、我们的客户端,怎么知道服务器的端口号的呢?

每一个服务器的端口号必须是众所周知的精心设计的,要被客户端熟知的,抖音自己的开发商在开发的时候,客户端和服务端的端口号都是内置的,都是被自己熟知的,所以我们使用者感觉不到这个,但是作为开发人员是要熟知服务器的端口号的。

6、一个进程可以绑定多个端口号吗?一个端口号可以被多个进程绑定吗?

显而易见:一个进程可以绑定多个端口号,但一个端口号不能被多个进程绑定。

二、两个协议

1、TCP协议(传输控制协议)

传输层协议 有连接 可靠传输(前提网络要联通,复杂,维护性要更强) 面向字节流

2、UDP协议(用户数据报协议)

传输层协议 无连接 不可靠传输(简单,但丢包问题解决不了) 面向数据报

三、网络字节序列

我们已经知道,内存中的多字节数据相对于内存地址有着大端和小端之分,磁盘文件中的数据相对于文件中的偏移地址也有着大端小端之分,网络数据流同样有着大端小端之分,那么如何定义网络数据流的地址呢?

发送主机通常按照内存从低到高的顺序往内存缓冲区中发送数据,接受主机也是按照内存从低到高的顺序去接说数据,然后保存 因此,网络数据流的地址应该这样规定,先发出的地址是低地址,后发出的地址是高地址 TCP/IP协议规定,网络数据流应该采用大端字节序,即低地址高字节 不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序来发送/接收数据; 如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即可;

为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。

这些函数名很好记:h标识host,n标识network,l标识32位的长整数,s标识十六位短整数 例如htonl表示的就是将32位的长整数从主机字节序转换为网络字节序 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回; 如果主机是大端字节序,这些 函数不做转换,将参数原封不动地返回。

四、socket编程接口

1、socket 常见API

代码语言:javascript
代码运行次数:0
复制
// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
// 绑定端口号 (TCP/UDP, 服务器) 
int bind(int socket, const struct sockaddr *address,
 socklen_t address_len);
// 开始监听socket (TCP, 服务器)
int listen(int socket, int backlog);
// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address,
 socklen_t* address_len);
// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr,
 socklen_t addrlen);

2、sockaddr结构

问题:为什么struct sockaddr* 不能写成void*呢? 因为刚开始网络出现的时候c语言还没有void*这个用法。

五、udp_socket_server代码编写

udp用的是SOCK_DGRAM,那么就是无连接不可靠的协议。

总体代码:Liunx仓库(1): Linux学习相关代码 - Gitee.com

六、udp_socket_client代码编写

1、客户端要绑定吗?

客户端是要有具体的ip值和port端口号的,所以是需要绑定的,但是很多人说不需要绑定,所以这种说法一定是错误的。有这种说法的原因是一般客户不需要自己显示的去绑定,但是操作系统是会进行随机选择的绑定的。 解释:前面我们说过了,一个端口号只能被一个进程所绑定,server端如此,client端也是如此,但是计算机有着成千上万个应用,虽然我们不可能一次性全部打开,但是我们总是会有开很多的情况, 我们假如说是这前十几个应用把常见的端口号都占了的话,我们后面的应用进程开启来的时候,就不能用这几个常见端口号,打开一次失败一次,试完了这几个常见端口号以后,再用其他冷门的端口号启动就变得很慢,用户自定义的端口号是很粗糙很不安全的,所以由OS操作系统随机的分配更加的安全和有效公平。其实客户端的端口号是多少并不重要,只要能够保证主机上的唯一性即可。 系统什么时候给我绑定端口号的呢?首次发送数据的时候,客户端就进行随机绑定端口号了(即客户端代码跑到sendto的时候)。

代码:Liunx仓库(1): Linux学习相关代码 - Gitee.com

七、地址转换函数

1、介绍

字符串转in_addr的函数:

in_addr转字符串的函数:

其中inet_pton和inet_ntop不仅可以转换IPv4的in_addr,还可以转换IPv6的in6_addr,因此函数接口是void*addrptr

2、关于inet_ntoa

inet_ntoa这个函数返回了一个char*, 很显然是这个函数自己在内部为我们申请了一块内存来保存ip的结果. 那么是否需要调用者手动释放呢?

man手册上说, inet_ntoa函数, 是把这个返回结果放到了静态存储区. 这个时候不需要我们手动进行释放. 那么问题来了, 如果我们调用多次这个函数, 会有什么样的效果呢? 参见如下代码:

因为inet_ntoa把结果放到自己内部的一个静态存储区, 这样第二次调用时的结果会覆盖掉上一次的结果.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、六个背景知识
    • 1、在进行网络通信时,是不是两台电脑在通信?
    • 2、端口号:
    • 3、端口号vs进程PID
    • 4、目的端口怎么跟客户端绑定的呢?也就是怎么通过目的端口去找到对应的进程的呢?
    • 5、我们的客户端,怎么知道服务器的端口号的呢?
    • 6、一个进程可以绑定多个端口号吗?一个端口号可以被多个进程绑定吗?
  • 二、两个协议
    • 1、TCP协议(传输控制协议)
    • 2、UDP协议(用户数据报协议)
  • 三、网络字节序列
  • 四、socket编程接口
    • 1、socket 常见API
    • 2、sockaddr结构
  • 五、udp_socket_server代码编写
    • 总体代码:Liunx仓库(1): Linux学习相关代码 - Gitee.com
  • 六、udp_socket_client代码编写
    • 1、客户端要绑定吗?
  • 七、地址转换函数
    • 1、介绍
    • 2、关于inet_ntoa
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档