linux【网络编程】之网络套接字预备

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

一、必备知识

在【网络基础】中我们提到了IP地址,接下来了解一下网络通信中其他方面的知识

1.1 端口号

  1. 端口号是一个2字节16位的整数;
  2. 端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来处理;
  3. 一个端口号只能被一个进程占用

通信原理
linux【网络编程】之网络套接字预备

  1. (公网)IP唯一标识一台主机,这样两台主机就可以发送接收数据,但是还需要区分数据发给那个软件

  2. 各自主机上的进程由端口号(port)唯一标识

  3. IP+端口号:表示该主机对应的服务进程在全网中是唯一的进程

软件之间的通信转换成进程,网络通信的本质就是进程间通信,客户端进程和服务端进程通过网络资源进行通信

1.2 端口号方面疑问及解决方案

  1. 不同主机上的端口号能一样吗?
    可以,IP保证了公网中主机的唯一性,port保证了主机内部的进程唯一性
  2. 端口号与进程之间的联系?
    同一台主机一个端口号只能被一个进程占用 ;一个进程可以绑定多个端口号; 但是一个端口号不能被多个进程绑定(os找不到)
  3. 进程已经有PID为什么还要有端口号?
    a.为了系统与网络解耦
    b.为了客户端迅速找到服务器进程–>IP+port不能随便改变(PID太容易被改变)
    c.不是所有进程都要提供网络服务,需要进行网络服务的拥有端口号
  4. 进程绑定port就变成了网络服务进程,OS是如何根据port找到对应的进程?
    底层OS维护了一张哈希表,根据port值找到对应的进程

二、TCP/UDP协议

这里仅仅是提一下,后面会结合实际、代码详细分析
TCP协议(传输控制协议)

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

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

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

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

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

三、网络字节流

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

  • 大端存储:低位高地址
  • 小端存储:低位低地址

如果一个大端机用大端的方式发送数据到一个小端机,网络需要识别发送方式,于是
TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节

  1. 不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序来发送/接收数据;
  2. 如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即可
  1. 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;(这里不管低地址处放的是高位还是低位)
  2. 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
  3. 网络数据流的地址规定:先发出的数据是低地址,后发出的数据是高地址

网络中接收和发送都是先低地址再高地址,解释数据的时候以大端存储来解释

网络字节序和主机字节序的转换可以直接调用库函数

#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位短整数。
例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回;
如果主机是大端字节序,这些 函数不做转换,将参数原封不动地返回。

四、socket编程

IP地址+端口号(port)能够标识该主机上的唯一进程:ip和端口号就叫为套接字

4.1 认识接口

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

4.2 浅析sockaddr结构

常见的套接字有三种:网络套接字,原始套接字,unix域间套接字
网络套接字主要运用于跨主机之间的通信,也能支持本地通信;域间套接字只能在本地通信;原始套接字可以跨过传输层(TCP/IP协议)访问底层的数据,为了方便使用,设计者只用了一套接口(小伙伴看到这里应该会想到一直常见的实现方式:多态!!!)

linux【网络编程】之网络套接字预备
上图可以看到sockaddr_in和sockaddr_un是两个不同的通信场景。区分它们就用前2个字节:16位地址类型协议家族的标识符(代表是本地通信还是网络通信),但是我们选择用sockaddr这个结构体

比如要进行网络通信,虽然参数是const struct sockaddr *addr,但实际传递进去的却是sockaddr_in结构体(类型不一样,注定要进行强制类型转换)。
在函数读取sockaddr前两个字节判断是什么通信类型然后再强转回去。

综上:可以把sockaddr看成基类,把sockaddr_in和sockaddr_un看成派生类,构成了多态
本篇文章为接下来网络程序模拟实现做铺垫,接口的详细认识及sockaddr会结合代码细细讲解,关注我,为你带来更多知识文章来源地址https://www.toymoban.com/news/detail-448799.html

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

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

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

相关文章

  • Linux网络编程(二-套接字)

    目录 一、背景知识 1.1 端口号 1.2 网络字节序 1.3 地址转换函数  二、Socket简介 三、套接字相关的函数  3.1 socket() 3.2 bind() 3.3 connect() 3.4 listen() 3.5 accept()  3.6 read()/recv()/recvfrom() 3.7 send()/sendto()  3.8 close()  四、UPD客服/服务端实验  1.1 端口号 端口号是访问服务器的标识 ,就好像

    2024年01月22日
    浏览(32)
  • 【Linux】网络编程套接字一

    上篇博客由唐僧的例子我们知道: 在IP数据包头部中,有两个IP地址,分别叫做源IP地址,和目的IP地址。 思考一下: 不考虑中间的一系列步骤,两台主机我们光有IP地址就可以完成通信了嘛? 想象一下发qq消息的例子,有了IP地址能够把消息发送到对方的机器上。 但是我们把

    2024年03月26日
    浏览(84)
  • 【Linux网络】网络编程套接字(TCP)

    目录 地址转换函数 字符串IP转整数IP 整数IP转字符串IP 关于inet_ntoa 简单的单执行流TCP网络程序 TCP socket API 详解及封装TCP socket  服务端创建套接字  服务端绑定  服务端监听  服务端获取连接  服务端处理请求 客户端创建套接字 客户端连接服务器 客户端发起请求 服务器测试

    2024年03月21日
    浏览(48)
  • 【Linux】网络---->套接字编程(TCP)

    TCP的编程流程:大致可以分为五个过程,分别是准备过程、连接建立过程、获取新连接过程、消息收发过程和断开过程。 1.准备过程:服务端和客户端需要创建各自的套接字,除此之外服务端还需要绑定自己的地址信息和进行监听。注意:服务端调用listen函数后,处理监听状

    2024年02月04日
    浏览(42)
  • Linux网络编程——tcp套接字

    本章Gitee仓库:tcp套接字 客户端: 客户端: 关于构造和初始化,可以直接在构造的时候,将服务器初始化,那为什么还要写到 init 初始化函数里面呢? 构造尽量简单一点,不要做一些“有风险”的操作。 tcp 是面向连接的,通信之前要建立连接,服务器处于等待连接到来的

    2024年02月20日
    浏览(37)
  • 【Linux】网络基础+UDP网络套接字编程

    只做自己喜欢做的事情,不被社会和时代裹挟着前进,是一件很奢侈的事。 1. 首先计算机是人类设计出来提高生产力的工具,而人类的文明绵延至今一定离不开人类之间互相的协作,既然人类需要协作以完成更为复杂的工作和难题,所以计算机作为人类的工具自然也一定需要

    2024年02月08日
    浏览(41)
  • 【Linux网络编程】网络编程套接字(TCP服务器)

    作者:爱写代码的刚子 时间:2024.4.4 前言:本篇博客主要介绍TCP及其服务器编码 只介绍基于IPv4的socket网络编程,sockaddr_in中的成员struct in_addr sin_addr表示32位 的IP地址 但是我们通常用点分十进制的字符串表示IP地址,以下函数可以在字符串表示和in_addr表示之间转换 字符串转in

    2024年04月14日
    浏览(52)
  • Linux网络编程- 原始套接字(Raw Socket)

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

    2024年02月07日
    浏览(33)
  • 【Linux Network】网络编程套接字(代码练习)—UDP

    目录 1. 常用接口 2. C/S 回声模拟 3. C/S myshell 的制作  Linux网络编程✨ 1. 常用接口 socket:创建套接字: 返回值: 套接字创建成功返回一个文件描述符 ,创建失败返回-1,同时错误码会被设置。 参数: domain: 网络通信 设置为 AF_INET(IPv4)或AF_INET6(IPv6) ; type:基于 UDP的网

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

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

    2024年02月12日
    浏览(39)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包