【网络】socket套接字基础知识

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

IP与端口号

  • IP

每台主机都有自己的IP地址,所以当数据从一台主机传输到另一台主机就需要IP地址。报头中就会包含源IP和目的IP

源IP地址:发送数据报那个主机的IP地址,目的IP地址:想发送到的那个主机的IP地址

我们把数据从一台主机传递到另一台主机不是真正目的,真正通信的不是这两个机器,其实是这两台机器上面的软件

应用层不止一个软件公网IP标识了一台唯一的主机,那么数据就可以由一台主机传递到另一台主机。但是有这么多的软件(进程),怎么保证软件A发送的被软件B接收呢?也就是说用什么来标识主机上客户或者服务进程的唯一性呢?

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

  • 端口号

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

由上面可以知道:

IP地址(标识主机全网唯一主机)+ 端口号(标识服务器上唯一的进程)能够标识网络上的某一台主机的某一个进程(全网唯一进程)

网络通信的本质就是进程间通信。而我们之前说过进程间通信的本质是看到同一份资源现在这个资源就是网络

通信的本质就是IO,因为我们上网的行为就两种情况:1.把数据发送出去 2.接收到数据。

标识一个进程有pid,那么为什么还需要端口号port呢?

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

一个端口号只能被一个进程占用,但是一个进程可以绑定多个端口号

底层OS如何根据port找到指定的进程——uint16(端口号)——task_struct——哈希

我们在网络通信的过程中,IP+port标识唯一性,IP有源IP和目的IP,port也有源端口号和目的端口号。所以我们在发送数据的时候也要把自己的IP和端口号发送过去,因为数据还要被发送回来。所以发送数据的时候一定会多出一部分数据(以协议的形式呈现)

TCP/UDP协议

我们用的套接字接口一定会使用传输层协议,不会绕过传输层去调用下面的协议。而传输层的协议分为TCP协议和UDP协议

  • TCP协议

TCP(Transmission Control Protocol 传输控制协议) 特点:

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

UDP(User Datagram Protocol 用户数据报协议) 特点:

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

注意:

理解不可靠传输:如发送数据时出现了丢包的情况、或者数据被重复传递了(传递了多份)、或者网络出现了问题等等造成的后果就叫做不可靠。所以传输层就是用来解决可靠性的一个协议。

可不可靠是一个中性词。可靠是需要成本的,往往在维护和编码上都比较复杂;而不可靠没有成本,使用起来也简单。所以要分场景使用。

网络字节流

我们知道内存中的多字节数据相对于内存地址有大端和小端之分。

小端:低权值的数放入低地址。(低低低)
大端:低权值的数放入高地址。

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

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

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

如何定义网络数据流的地址:

发送主机把发送缓冲区中的数据按内存地址从低到高的顺序发出
接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存

也就是说先发出的数据是低地址,后发出的数据是高地址

TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节 不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序来发送/接收数据;如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即可

把数据转化成大端的工作可不需要我们自己来做,那太麻烦了,可以调用库函数做网络字节序和主机字节序的转换即可:

#include <arpa/inet.h>
// 主机序列转网络序列
uint16_t htons(uint16_t hostshort);
uint32_t htonl(uint32_t hostlong);
// 网络序列转主机序列
uint16_t ntohs(uint16_t netshort);
uint32_t ntohl(uint32_t netlong);

**h表示host,n表示network,l表示32位长整数,s表示16位短整数。**主机是大端还是小端在函数内部会自己进行判断。
如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回。
如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。

如果是其他数据类型呢?不用担心,未来网络发送的时候所有数据都是字符串;发送数据时使用的原生接口对于字符串信息自动转化

socket套接字接口

  • socket常见API
// 创建 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);

IP地址+端口号能够标识该主机上的唯一的一个进程:ip和端口号port就叫为套接字,socket就是插座的意思,未来进行网络通信时,插头和插座配套使用。

函数参数里面有个叫sockaddr的结构体类型,这个我们需要了解一下👇

  • sockaddr的结构体

套接字种类是比较多的。常见的有三种:

1.网络套接字

2.原始套接字

3.unix域间套接字

我们主要了解第一个网络套接字

网络套接字主要运用于跨主机之间的通信,也能支持本地通信,而域间套接字只能在本地通信。而原始套接字可以跨过传输层(TCP/IP协议)访问底层的数据。这些套接字应用场景完全不同,所以我们想用就得用三套不同的接口。而为了方便,设计者只设计了一套接口,就可以通过不同的参数,解决所有网络或者其他场景下的通信问题。

这里举两个具体的套接字类型:sockaddr_in(inet,网络通信)sockaddr_un(unix,域间套接)

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是两个不同的通信场景。区分它们就用前2个字节:16地址类型协议家族的标识符(代表是本地通信还是网络通信)。 我们两个结构体都不用,直接用sockaddr。未来进行网络编程时,如果是网络通信,填充的网络信息是struct sockaddr_in这个结构体。

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

接口的设计为什么是structaddr*结构,C语言为了能够接收任意类型是void*,为什么不使用void*,而且void*不用强转

因为设计这一批接口时C语言标准还没有void*

这是OS的接口,不可随意更改,其他语言可能不支持void*

所以这就相当于:可以把sockaddr看成基类,把sockaddr_insockaddr_un看成派生类,构成了多态体系

总结

IP地址+端口号port可以标识网络上的某一台主机的某一个进程(全网唯一)

TCP/UDP协议都是传输层的协议,其他特点不同:如UDP是不可靠的

套接字是一种网络通信的机制,IP+端口号port是套接字的形式,网络字节序列规定为大端,规定网络中的数据是大端的。

sockaddr使用统一的接口解决所有网络或者其他场景下的通信问题文章来源地址https://www.toymoban.com/news/detail-438390.html

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

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

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

相关文章

  • Java网络编程基础:TCP Socket套接字编程 IntAddress UDP等...

    目录 一,网络基础 1.IP地址 2.端口 3.TCP/UDP协议 4.网络编程开发模式  二,基于套接字的Java网络编程 1.Socket  2.InetAddress 三.基于TCP的Socket网络编程 1.单服务器端与单Socket客户端一次通讯 2.单服务器端接收多次通讯  3.TCP网络通讯补充 四,基于UDP的网络编程 1. DatagramSocket:收发

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

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

    2024年02月15日
    浏览(43)
  • 【网络协议】聊聊套接字socket

    网络编程我们知道是通过socket进行编程的,其实socket也是基于TCP和UDP协议进行编程的。但是在socket层面是感知不到下层的,所以在设置参数的时候,其实是端到端协议智商的网络层和传输层。TCP是数据流所以设置为SOCK_STREAM,而UDP是基于数据报的,设置为SOCK_DGRAM 整体流程其实

    2024年02月07日
    浏览(32)
  • 【网络编程】socket套接字

    如果我们的台式机或者笔记本没有IP地址就无法上网,而因为每台主机都有IP地址,所以注定了数据从一台主机传输到另一台主机 一定有源IP和目的IP 。 所以在报头中就会包含源IP和目的IP。 而我们把数据从一台主机传递到另一台主机并不是目的,真正通信的其实是应用层上的

    2024年02月02日
    浏览(45)
  • 网络编程套接字(Socket)

    认识IP地址, 端口号, 网络字节序等网络编程中的基本概念; 学习socket api的基本用法; 能够实现一个简单的udp客户端/服务器; 能够实现一个简单的tcp客户端/服务器(单连接版本, 多进程版本, 多线程版本); 理解tcp服务器建立连接, 发送数据, 断开连接的流程; 通俗易懂地说,源

    2024年01月21日
    浏览(38)
  • 【计算机网络】socket 网络套接字

    实际上我们两台机器在进行通信时,是应用层在进行通信,应用层必定会推动下层和对方的上层进行通信。 其实网络协议栈中的下三层,主要解决的是数据安全可靠的送到远端机器。而用户使用应用层软件,完成数据发送和接收的。那么用户要使用软件,首先需要把这个软件

    2024年02月22日
    浏览(32)
  • 网络编程—Socket套接字详解

    目录 一、网络编程 1.1、为什么需要网络编程? 1.2、什么是网络编程 1.3、发送端和接收端 ​编辑1.4、请求和响应 ​编辑1.5、客户端和服务端  二、Socket套接字  2.1、概念 2.2、分类  2.2.1、流套接字  2.2.2、数据报套接字  2.2.3、原始套接字  2.3、Socket编程注意事项  1.1、为什

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

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

    2024年02月03日
    浏览(38)
  • [JAVAee]网络编程-套接字Socket

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

    2024年02月13日
    浏览(34)
  • socket | 网络套接字、网络字节序、sockaddr结构

    欢迎关注博主 Mindtechnist 或加入【Linux C/C++/Python社区】一起学习和分享Linux、C、C++、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。 专栏:《网络编程》 Socket本身有“插座”的意思

    2024年02月05日
    浏览(28)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包