【网络】网络编程套接字

一、知识提及

1.源IP地址和目的IP地址

在IP数据包头部中, 有两个IP地址, 分别叫做源IP地址, 和目的IP地址

2.端口号

端口号(port)是传输层协议的内容. 

  • 端口号是一个2字节16位的整数;
  • 端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来处理;
  • IP地址 + 端口号能够标识网络上的某一台主机的某一个进程;
  • 一个端口号只能被一个进程占用.

我们网络通信的本质就是进程间通信,不过是在不同的主机上。

IP地址能标识唯一的一台主机,端口号port可以用来标识主机上唯一的一个进程。

IP :Port = 标识全网唯一的一个进程。

用客户端ip:客户端端口号和服务端ip:服务端端口号的通信就是socket

pid 表示唯一一个进程; 此处我们的端口号也是唯一表示一个进程. 那么这两者之间是怎样的关系?

  1. 不是所有的进程都要网络通信,但是所有进程都要有pid。
  2. 系统和网络功能解耦

源端口号和目的端口号

传输层协议(TCP和UDP)的数据段中有两个端口号, 分别叫做源端口号和目的端口号. 就是在描述 "数据是谁发的, 要发给谁";

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

一个进程可以绑定多个端口号。

一个端口号不可以被多个进程绑定。

 3.TCP协议

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

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

4.UDP协议 

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

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

5.网络字节序 

我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分(把一个数据的高权值位放在地址较高的地方或把一个数据的低权值位放在地址较低的地方,这就是小端,反之就是大端), 磁盘文件中的多字节数据相对于文件中的偏 移地址也有大端小端之分, 网络数据流同样有大端小端之分. 那么如何定义网络数据流的地址呢?

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

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

#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编程接口

1.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);

 2.sockaddr 结构

socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,以及后面要讲的UNIX Domain Socket. 然而, 各种网络协议的地址格式并不相同.

 套接字编程的种类

  1. 域间套接字编程 -- 在同一个机器内
  2. 原始套接字编程 -- 跳过传输层,通常用于网络工具
  3. 网络套接字编程 -- 用于用户间的网络通信

网络接口的设计者并不想设计三套接口,而是想将网络接口抽象统一化,而想统一,接口的参数必须是一样的。

  • IPv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位地址类型, 16 位端口号和32位IP地址.
  • IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6. 这样,只要取得某种sockaddr结构体的首地址, 不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容.
  • socket API可以都用struct sockaddr *类型表示, 在使用的时候需要强制转化成sockaddr_in; 这样的好处是程序的通用性, 可以接收IPv4, IPv6, 以及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数

3.设计一个简单的UDP网络程序

netstat -nltp

查看网络连接

如何实现 整数IP和字符串IP 的相互转换?

设置一个ip结构体,每个成员都是一个一字节整数

struct ip
{uint8_t part1;uint8_t part2;uint8_t part3;uint8_t part4;
};

1.将整数转换为字符串

假如现在有一个整数IP地址, int src_ip = 123456789;

将它强转成为struct ip*类型, struct ip* p = (struct ip*)src_ip;

然后,string ip = to_string(p->part1) + "."  + to_string(p->part2) + "."  + to_string(p->part3) + "."  + to_string(p->part4);

就可以转成字符串格式了。

2.将字符串转换为整数

假如现在有个字符串IP地址, string ip = "192.168.233.148";

将它切分成 "192"  "168"  "233"  "148"

先定义一个32位整数, uint32_t IP;

取地址强转成struct ip*, struct ip* x = (struct ip*)&IP;

然后就可以

x->part1 = stoi("192");

依次类推,再强转成uint32_t类型,就可以得到一个整数IP。

但是,我们库里有相关的系统调用函数,就不需要我们手写了,我们明白其原理即可。

in_addr_t inet_addr(const char *cp);

端口号 [0~1024]基本上是系统内置的端口号,最好绑定1024以上的端口号,而1024以上的端口号有些也不能轻易绑定,比如mysql的3306端口号。

提问:客户端需要绑定socket吗?

答:要!只不过不需要用户显示的绑定!一般由OS自由随机选择!

一个端口号只能被一个进程bind,对server是如此,对client,也是如此!

client为了防止不同的应用争抢端口号发生冲突,通常是由OS分配。

client的port是多少,其实不重要,只要保证主机上的唯一性即可!

127.0.0.1:本地环回地址 ,通常用它来进行cs的测试

源码可以点击下面的地址查看

test512 · AoDong/Linux-test - 码云 - 开源中国 (gitee.com)

为我们这个Udp实现Windows做客户端,Linux做服务器的收发消息的程序

#include <iostream>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <WinSock2.h>
#include <Windows.h>#pragma warning(disable:4996)#pragma comment(lib, "ws2_32.lib")const static uint16_t port = 8080;
const static std::string ip = "192.168.233.138";int main()
{std::cout << "hello socket!" << std::endl;WSADATA wsd;WSAStartup(MAKEWORD(2, 2), &wsd);SOCKET sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){std::cout << "client create socket error" << std::endl;exit(1);}struct sockaddr_in server;//bzero(&server, sizeof(server));memset(&server, 0, sizeof(server));server.sin_family = AF_INET;server.sin_addr.s_addr = inet_addr(ip.c_str());server.sin_port = htons(port);int len = sizeof(server);std::string message;char buffer[1024];while (true){std::cout << "Please Enter@ ";std::getline(std::cin, message);sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr*)&server, len);struct sockaddr_in tmp;int len1 = sizeof(tmp);int s = recvfrom(sockfd, buffer, 1023, 0, (struct sockaddr*)&tmp, &len1);if (s > 0){buffer[s] = '\0';//std::cout << buffer << std::endl;}}closesocket(sockfd);WSACleanup();return 0;
}

4.设计一个简单的TCP网络程序

int listen(int sockfd, int backlog); //listen for connections on a socket
//accept a connection on a socket
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
initiate a connection on a socket
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
在服务器得到新连接时,单进程版服务就不太适用了,所以我们就要用到多进程,而多进程,我们的子进程就会继承两个文件描述符,ListenSock_和sockfd,我们在子进程中关不关闭ListenSock_,但是父进程强烈要求关闭sockfd。

 hao

在执行程序时,在后面加个&,表明将当前进程设置为后台进程运行。

jobs:查看后台进程。

fg 任务号:将该后台进程提至前台进程

在当前前台进程运行时,在键盘输入ctrl+z暂停,就是说像当前运行前台进程发送了一个19号信号,SIGSTOP。它会被暂停中止,并自动转为后台进程,此时bash就自动被提至前台进程。因为在命令行中,前台进程要一直存在。

bg 任务号:将暂停的后台进程恢复为前台进程

SID:进程组

打开linux,系统会创建一个bash进程,和一个session(会话),session会以bash的pid为SID创建新的进程组。

如果使进程不受用户登录或者注销的影响,就可以 -- 守护进程化。

自成进程组 自成会话的进程,守护进程

NAMEsetsid - creates a session and sets the process group IDSYNOPSIS#include <sys/types.h>#include <unistd.h>pid_t setsid(void);
DESCRIPTIONsetsid()  creates a new session if the calling process is not a process group leader.  The calling process is the leader of the new session (i.e., its session ID is made thesame as its process ID).  The calling process also becomes the process group leader of a new process group in the session (i.e., its process group ID is made the same as itsprocess ID).The calling process will be the only process in the new process group and in the new session.Initially, the new session has no controlling terminal.  For details of how a session acquires a controlling terminal, see credentials(7).

注:

  • 这个进程不能是进程组的组长        

守护进程的本质 -- 孤儿进程

static const std::string nullfile = "/dev/null";void Daemon(const std::string &cwd = "")
{// 1.忽略其它信号signal(SIGCHLD, SIG_IGN);signal(SIGPIPE, SIG_IGN);signal(SIGSTOP, SIG_IGN);// 2.将自己变为独立的会话if(fork() > 0) exit(0);setsid();// 3.更改当前调用进程的工作目录if(!cwd.empty()) chdir(cwd.c_str());// 4.标准输入、输出和错误 重定向至/dev/nullint fd = open(nullfile.c_str(), O_RDWR);if(fd >0){dup2(fd, 0);dup2(fd, 1);dup2(fd, 2);close(fd);}
}

但是我们系统中也提供了一个这个函数 Deamon

int daemon(int nochdir, int noclose);

代码:test517 · AoDong/Linux-test - 码云 - 开源中国 (gitee.com) 

三、简单地谈一下TCP协议

TCP是全双工的,接收消息和发送消息是可以同时进行的。

TCP是一个传输控制协议

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/18708.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文介绍数据和模型漂移(Drift):漂移检测示例

大家好&#xff0c;漂移(Drift)是机器学习中用来描述模型在生产环境中随着时间推移而性能逐步下降的现象&#xff0c;由很多原因引起&#xff0c;主要原因是随着时间推移输入数据&#xff08;x&#xff09;分布的变化和期望目标&#xff08;y&#xff09;之间的关系发生了变化。…

PHP MySQL图解学习指南:开启Web开发新篇章

PHP曾经是最流行的Web开发语言&#xff0c;许多世界领先的网站(如Facebook、维基百科和WordPress)都是用它编写的。PHP运行在Web服务器端&#xff0c;通过使用存储在MySQL数据库中的数据&#xff0c;使得网站可以为每一位访问者显示不同的定制页面。书中采用简单、直观的图示化…

STL-priority_queue的使用及其模拟实现

优先级队列(priority_queue)默认使用vector作为其底层存储数据的容器&#xff0c;在vector上又使用了堆算法将vector中的元素构造成堆的结构&#xff0c;因此priority_queue就是堆&#xff0c;所有需要用到堆的位置&#xff0c;都可以考虑使用priority_queue。 注意&#xff1…

可选链与空值合并运算符的妙用

可选链&#xff08;Optional Chaining&#xff09;和空值合并运算符&#xff08;Nullish Coalescing Operator&#xff09;是 JavaScript 中的两个新特性&#xff0c;它们可以在处理可能为 null 或 undefined 的值时提供更简洁和安全的代码。 可选链允许我们通过在对象的属性后…

【好书分享第十三期】AI数据处理实战108招:ChatGPT+Excel+VBA

文章目录 一、内容介绍二、内页插图三、作者简介四、前言/序言五、目录 一、内容介绍 《AI数据处理实战108招&#xff1a;ChatGPTExcelVBA》通过7个专题内容、108个实用技巧&#xff0c;讲解了如何运用ChatGPT结合办公软件Excel和VBA代码实现AI办公智能化、高效化。随书附赠了…

NDIS驱动开发-NET_BUFFER体系

网络数据由通过网络发送或接收的数据包组成。 NDIS 提供数据结构来描述和组织此类数据。 NDIS 6.0 及更高版本的主要网络数据结构包括&#xff1a; NET_BUFFERNET_BUFFER LISTNET_BUFFER_LIST_CONTEXT 它们之间的关系如下: 在 NDIS 6.0 及更高版本中&#xff0c; NET_BUFFER …

AI工程师:高薪时代的领跑者

在科技飞速发展的今天&#xff0c;人工智能&#xff08;AI&#xff09;技术正日益成为推动社会进步的关键力量。与此同时&#xff0c;AI领域的人才需求也呈现出井喷之势&#xff0c;其中AI工程师更是成为了各大企业竞相争夺的“香饽饽”。根据最新数据显示&#xff0c;AI工程师…

串口调试助手中文乱码 解决方案

输出乱码 一般&#xff0c;当串口调试助手输出乱码时&#xff0c;可能有以下几个原因&#xff1a; 波特率设置错误&#xff1a;串口通信需要保证发送和接收的设备使用相同的波特率。请检查串口调试助手和目标设备的波特率设置是否一致。 数据位、停止位或校验位设置错误&…

支持向量机、随机森林、K最近邻和逻辑回归-九五小庞

支持向量机&#xff08;Support Vector Machine, SVM&#xff09;、随机森林&#xff08;Random Forest&#xff09;、K最近邻&#xff08;K-Nearest Neighbors, KNN&#xff09;和逻辑回归&#xff08;Logistic Regression&#xff09;是机器学习和统计学习中常用的分类算法。…

【目标解算】相机内外参数详细解读+坐标系转换

一、相机参数介绍 1.1 相机内参矩阵 概念&#xff1a;内参矩阵用于描述相机的内部参数&#xff0c;它包含了相机的焦距、主点坐标和图像的畸变等信息。内参矩阵的形式通常为一个3x3的矩阵&#xff0c;常用表示为K。内参矩阵可以将相机坐标系中的三维点映射到图像平面上的二维…

C++设计模式之策略模式、迭代器模式、适配器模式、工厂模式、超级工厂模式、享元模式、代理模式

文章目录 一、介绍1.毫无价值的使用虚函数例子 二、策略模式1.策略模式2.多重策略与迭代器模式3.不要什么东西都塞一块 三、适配器模式1.跨接口的适配器2.跨接口的适配器 四、工厂模式1.工厂模式2.超级工厂模式3.RAII 自动管理内存4.工厂模式实战 五、享元模式1.享元模式2.代理…

linux安装mysql后,配置mysql,并连接navicat软件

Xshell连接登陆服务器 输入全局命令 mysql -u root -p 回车后&#xff0c;输入密码&#xff0c;不显示输入的密码 注意mysql服务状态&#xff0c;是否运行等 修改配置文件my.cnf&#xff0c;这里没找到就找my.ini&#xff0c;指定有一个是对的 find / -name my.cnf 接下…

GPT-4你了解多少呢

一、引言 在人工智能&#xff08;AI&#xff09;领域&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术一直备受关注。近年来&#xff0c;随着深度学习技术的飞速发展&#xff0c;NLP领域也取得了显著进步。GPT-4&#xff0c;作为OpenAI公司最新发布的自然语言处理模型…

bochs 调试基本指令大全

bochs 调试基本指令大全 功能 指令 举例 在某物理地址设置断点 b addr b 0x90000 运行到断点位置 c c 单步运行&#xff08;遇到函数则进入&#xff09; s s 单步运行&#xff08;遇到函数则跳过&#xff09; n n 继续运行上调指令 回车 回…

liunx进程和计划任务管理

文章目录 一、进程特殊情况 二、查看进程2.1进程查看2.2补充说明 三、进程管理3.1运维的指标五大负载 3.2定时任务、计划任务 一、进程 进程管理 相当于任务管理器 进程就是运行起来的代码 线程&#xff1a;线程相当于复制了进程的部分代码&#xff0c;程序运行起来之后&…

2024-03-23青少年软件编程(Python语言)等考(五级)解析

2024-03-23青少年软件编程(Python语言)等考(五级)解析一、单选题(共25题,共50分) 1.以下代码的输出结果是?( A ) nums = list(range(100, 201)) print(nums[::10]) A.[100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200] B.[100, 101, 102, 103, 104, 105, 106…

京东二面:为什么Netty要造FastThreadLocal?

FastThreadLocal 从字面意义上来看&#xff0c;它是“Fast”“ThreadLocal”的结合体&#xff0c;寓意为快速的 ThreadLocal。那么&#xff0c;问题来了&#xff0c;Netty 为什么要再造一个 FastThreadLocal&#xff1f;FastThreadLocal 运行快的原因是啥&#xff1f;除了快之外…

linnux上安装php zip(ZipArchive)、libzip扩展

安装顺序&#xff1a; 安装zip&#xff08;ZipArchive&#xff09;&#xff0c;需要先安装libzip扩展 安装libzip&#xff0c;需要先安装cmake 按照cmake、libzip、zip的先后顺序安装 下面的命令都是Linux命令 1、安装cmake 确认是否已安装 cmake --version cmake官网 未安装…

项目十 网络服务器搭建及应用

文章目录 Samba1.配置yum源2.安装samba服务和客户端3.添加用户4.修改访问控制权限&#xff0c;使samba指定的目录可以正常访问5.修改samba配置参数6.启动samba服务7.查看samba运行情况8.通过外部服务器访问 I know, i know 地球另一端有你陪我 Samba 1.配置yum源 mkdi…

【Paddle】稀疏计算的使用指南 稀疏ResNet的学习心得 (2) + Paddle3D应用实例稀疏 ResNet代码解读 (1.6w字超详细)

【Paddle】稀疏计算的使用指南 & 稀疏ResNet的学习心得 Paddle3D应用实例稀疏 ResNet代码解读 写在最前面一、稀疏格式简介1. COO&#xff08;Coordinate Format&#xff09;2. CSR&#xff08;Compressed Sparse Row Format&#xff09; 二、Paddle稀疏张量支持1. 创建 C…