【网络编程】socket套接字

这篇具有很好参考价值的文章主要介绍了【网络编程】socket套接字。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、源IP和目的IP

如果我们的台式机或者笔记本没有IP地址就无法上网,而因为每台主机都有IP地址,所以注定了数据从一台主机传输到另一台主机一定有源IP和目的IP
所以在报头中就会包含源IP和目的IP。

而我们把数据从一台主机传递到另一台主机并不是目的,真正通信的其实是应用层上的软件。
【网络编程】socket套接字
而我们知道应用层可不止一个软件

那么我们现在就有了问题:
既然有了公网IP标识了一台唯一的主机,那么数据就可以由一台主机传递到另一台主机。但是有这么多的软件(进程),怎么保证软件A发送的被软件B接收呢?
换句话说:用什么来标识主机上的进程的唯一性呢?

二、端口号port

为了更好的表示一台主机上服务进程的唯一性,规定用端口号port标识服务进程、客户端进程的唯一性。

端口号:

1️⃣ 端口号是一个2字节16位的整数
2️⃣ 端口号用来标识一个进程,告诉操作系统要把数据交给哪一个进程
3️⃣ 一个端口号只能被一个进程占用(同一个主机)

由上面可以知道:
IP地址(标识唯一主机)+ 端口号(标识唯一进程)能够标识网络上的某一台主机的某一个进程(全网唯一进程)。

那么网络通信的本质就是进程间通信。
而我们之前说过进程间通信的本质是看到同一份资源现在这个资源就是网络
而通信的本质就是IO,因为我们上网的行为就两种情况:1.把数据发送出去 2.接收到数据。

这里再思考一个问题,我们标识一个进程有pid,那么为什么还需要端口号呢?

1️⃣ 首先pid是系统规定的,而port是网络规定的,这样就可以把系统和网络解耦
2️⃣ port标识服务器的唯一性不能做任何改变,要让客户端能找到服务器,就像110,120样不能被改变。而pid每次启动进程pid就会改变。
3️⃣ 不是所有的进程都需要提供网络服务或请求(不需要port),但每个进程都需要pid。

虽然一个端口号只能绑定一个进程,但是一个进程可以绑定多个端口号。

上面我们说了IP有源IP和目的IP,而这里的port也有源端口号和目的端口号。我们在发送数据的时候也要把自己的IP和端口号发送过去,因为数据还要被发送回来。所以发送数据的时候一定会多出一部分数据(以协议的形式呈现)。

有人可能会问那么第一次怎么知道给哪个IP和port发送,这个不用担心,因为服务器内部已经内置好了。

三、TCP/UDP协议

我们用的套接字接口一定会使用传输层协议,我们不会绕过传输层去调用下面的协议。
【网络编程】socket套接字

而传输层的协议分为TCP协议和UDP协议。

对于TCP协议有几个特点:

1️⃣ 传输层协议
2️⃣ 有连接(正式通信前要先建立连接)
3️⃣ 可靠传输(在内部帮我们做可靠传输工作)
4️⃣ 面向字节流

对于UDP协议有几个特点:

1️⃣ 传输层协议
2️⃣ 无连接
3️⃣ 不可靠传输
4️⃣ 面向数据报

可靠和不可靠传输:
不可靠传输:比如说发送数据时出现了丢包的情况、或者数据被重复传递了(传递了多份)、或者网络出现了问题等等造成的后果就叫做不可靠。

所以传输层就是用来解决可靠性的一个协议。

但是为什么UDP不可靠传输我们还要有这个协调呢?
这里要注意可不可靠是一个中性词。可靠是需要成本的,往往在维护和编码上都比较复杂;
而不可靠没有成本,使用起来也简单。
所以要分场景使用

3.1 网络字节流

我们知道多字节数据存储的时候会有大小端问题。
小端:低权值的数放入低地址。
大端:低权值的数放入高地址。

所以现在就出现了这么一种情况:可能一个大端机用大端的方式发送数据到一个小端机。
现在跨网络我们也不知道数据到底是大端和小端

所以就有了规定:
网络中的数据都是大端。

发送数据的主机如果是大端机就不用管,如果是小端机就把小端转成大端再发送。
接收数据同理。

那么如何定义网络数据流的地址呢?

发送主机把发送缓冲区的数据按内存的地址从低到高进行发送。
接收主机把接收缓冲区的数据按内存的地址从低到高进行接收。
也就是先发送的数据是低地址,后发送的数据是高地址。
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,l表示32位长整数,s表示16位短整数。
主机是大端还是小端在函数内部会自己进行判断。
如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回。
如果主机是大端字节序,这些 函数不做转换,将参数原封不动地返回。

四、socket套接字

前面我们说过IP+端口号port标识了全网唯一的进程,我们IP+port就叫做套接字socket

4.1 socket常见接口

// 创建 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);

可以发现函数参数里面有个叫sockaddr的结构体类型,这是什么呢?

4.2 sockaddr结构体

其实套接字有不少种类型。
常见的有三种:

网络套接字
原始套接字
域间套接字

网络套接字主要运用于跨主机之间的通信,也能支持本地通信,而域间套接字只能在本地通信。而原始套接字可以跨过传输层(TCP/IP协议)访问底层的数据。

这些套接字应用场景完全不同,所以我们想用就得用三套不同的接口。
而为了方便,设计者只使用了一套接口,就可以通过不同的参数,解决所有的通信场景。

这里举两个具体的套接字类型:sockaddr_insockaddr_un

struct sockaddr_in {
    short int sin_family;           // 地址族,一般为AF_INET
    unsigned short int sin_port;    // 端口号,网络字节序
    struct in_addr sin_addr;        // IP地址
    unsigned char sin_zero[8];      // 用于填充,使sizeof(sockaddr_in)等于16
};

struct sockaddr_un {
    sa_family_t sun_family;       /* AF_UNIX */
    char sun_path[108];    /* 带有路径的文件名 */
};

【网络编程】socket套接字
可以看到sockaddr_insockaddr_un是两个不同的通信场景。区分它们就用16地址类型协议家族的标识符。 我们两个结构体都不用,用sockaddr

比方说我们想用网络通信,虽然参数是const struct sockaddr *addr,但实际传递进去的却是sockaddr_in结构体(注意要强制类型转换)。
在函数内部一视同仁,全部看成sockaddr类型,然后根据前两个字节判断到底是什么通信类型然后再强转回去。

我们可以把sockaddr看成基类,把sockaddr_insockaddr_un看成派生类,构成了多态体系。

五、总结

1️⃣ IP+port可以标志全网唯一进程。
2️⃣ 套接字是一种通信机制(通信的两方的一种约定),而套接字的表示形式:IP+port
3️⃣ TCP和UDP的主要区别就是可靠传输和不可靠传输,而可不可靠是中性词。
4️⃣ 网络字节序列简单粗暴的规定为大端。
5️⃣ sockaddr用统一的接口方式来解决网络通信的大部分问题。
Socket可以看成在两个程序进行通讯连接中的一个端点,一个程序将一段信息写入Socket中,该Socket将这段信息发送给另外一个Socket中,使这段信息能传送到其他程序中。文章来源地址https://www.toymoban.com/news/detail-431396.html



到了这里,关于【网络编程】socket套接字的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [JAVAee]网络编程-套接字Socket

    目录 基本概念 发送端与接收端 请求与响应 ​编辑客户端与服务器 Socket套接字  分类 数据报套接字 流套接字传输模型   UDP数据报套接字编程 DatagramSocket API DatagramPacket API InetSocketAddress API 示例一: 示例二: TCP流数据报套接字编程 ServerSocket API Socket API 示例一:   网络编程指的

    2024年02月13日
    浏览(56)
  • 【Python】Python 网络编程 ( Socket 套接字简介 | Socket 套接字使用步骤 | Socket 套接字服务端与客户端开发 )

    Socket 套接字 是一种 进程之间的 通信机制 , 通过套接字可以在 不同的进程之间 进行数据交换 ; 在 网络编程 中 , Socket 套接字 主要用于 客户端 与 服务器 之间的 通信 , 大部分 网络相关的应用程序 , 都使用到了 Socket 套接字技术 ; 套接字有两种类型 : 流套接字 : 提供了一个可

    2024年02月15日
    浏览(153)
  • 网络编程『socket套接字 ‖ 简易UDP网络程序』

    🔭个人主页: 北 海 🛜所属专栏: Linux学习之旅、神奇的网络世界 💻操作环境: CentOS 7.6 阿里云远程服务器 在当今数字化时代,网络通信作为连接世界的桥梁,成为计算机科学领域中至关重要的一部分。理解网络编程是每一位程序员必备的技能之一,而掌握套接字编程则

    2024年02月04日
    浏览(57)
  • 【网络通信】socket编程——TCP套接字

    TCP依旧使用代码来熟悉对应的套接字,很多接口都是在udp中使用过的 所以就不会单独把他们拿出来作为标题了,只会把第一次出现的接口作为标题 通过TCP的套接字 ,来把数据交付给对方的应用层,完成双方进程的通信 在 tcpServer.hpp 中,创建一个命名空间 yzq 用于封装 在命名

    2024年02月13日
    浏览(51)
  • Linux网络编程- 原始套接字(Raw Socket)

    原始套接字(Raw Socket)提供了一种机制,允许应用程序直接访问底层传输协议,绕过操作系统提供的传输层接口。这种套接字通常用于实现新的协议或对现有协议进行低级别的操作。 以下是对原始套接字的详细介绍: 定义与用途 : 原始套接字是直接基于网络层(如IP)的。

    2024年02月07日
    浏览(55)
  • 【JavaEE初阶】 网络编程基础与Socket套接字

    用户在浏览器中,打开在线视频网站,如腾讯看视频,实质是通过网络,获取到网络上的一个视频资源。 与本地打开视频文件类似,只是视频文件这个资源的来源是 网络 。 相比本地资源来说,网络提供了更为丰富的网络资源: 所谓的网络资源,其实就是在网络中可以获取

    2024年02月05日
    浏览(65)
  • 网络编程之 Socket 套接字(使用数据报套接字和流套接字分别实现一个小程序(附源码))

    网络编程是指网络上的主机,通过不同的进程,以编程的方式实现 网络通信(或称为网络数据传输) 只要满足不同的进程就可以进行通信,所以即便是在同一个主机,只要不同的进程,基于网络传输数据,也属于网络编程 在一次网络传输中: 发送端: 数据的 发送方进程

    2024年02月03日
    浏览(62)
  • 【网络编程】网络编程概念,socket套接字,基于UDP和TCP的网络编程

    前言: 大家好,我是 良辰丫 ,今天我们一起来学习网络编程,网络编程的基本概念,认识套接字,UDP与TCP编程.💞💞💞 🧑个人主页:良辰针不戳 📖所属专栏:javaEE初阶 🍎励志语句:生活也许会让我们遍体鳞伤,但最终这些伤口会成为我们一辈子的财富。 💦期待大家三连,关注

    2023年04月20日
    浏览(61)
  • 网络编程day1——进程间通信-socket套接字

            基本特征:socket是一种接口技术,被抽象了一种文件操作,可以让同一计算机中的不同进程之间通信,也可以让不同计算机中的进程之间通信(网络通信)         进程A                                                        进程B     创建socket对象

    2024年02月10日
    浏览(89)
  • 【Linux网络】网络编程套接字 -- 基于socket实现一个简单UDP网络程序

    我们把数据从A主机发送到B主机,是目的吗?不是,真正通信的不是这两个机器!其实是这两台机器上面的软件(人) 数据有 IP(公网) 标识一台唯一的主机 ,用谁来标识各自主机上客户或者服务进程的唯一性呢? 为了更好的表示一台主机上服务进程的唯一性,我们采用 端口号

    2024年02月12日
    浏览(158)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包