当前位置: 首页 > news >正文

编写一个最简单的Linux服务端和客户端程序

2023年8月3日,周四下午

这篇文章我从下午开始写了几个小时,

这篇文件基本总结了我今天学到的知识,

在写这篇文章的过程中灵感不断涌现、想明白了很多知识点,非常酣畅淋漓。

什么叫做深度学习?这就是深度学习!深度学习就是打破砂锅问到底,就是不断提出问题和解决问题。

有点飘了,感觉自己也能写书和出书了,哈哈哈。

其实我感觉自己还没写完,还有些疑惑没解决,以后有空再更新。


目录

  • 纯享版
  • 功能
  • 服务端程序
  • 客户端程序
  • 通俗版
  •  服务端程序
  • 客户端程序
  • 讲解版
  • 服务端程序
  • 为什么要设置服务器端口号?
  • 为什么不需要设置服务端的IP地址?
  • INADDR_ANY是什么意思?
  • 怎么获取到客户端的IP地址和端口号?
  • ​编辑
  • 怎么理解listen(serv_sock,5)?
  • 客户端程序

纯享版

功能

服务端负责发送Hello给客户端,

客户端负责把Hello接收并打印出来。

服务端程序

#include<sys/socket.h>
#include<arpa/inet.h>
#include<string.h>
int main(){int serv_sock=socket(AF_INET,SOCK_STREAM,0);struct sockaddr_in serv_addr;memset(&serv_addr,0,sizeof(serv_addr));serv_addr.sin_family=AF_INET;serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);serv_addr.sin_port=htons(9990);bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr));listen(serv_sock,5);struct sockaddr_in clnt_addr;socklen_t clnt_addr_size=sizeof(clnt_addr);int clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_size);write(clnt_sock,"Hello",sizeof("Hello"));close(clnt_sock);close(serv_sock);return 0;
}

客户端程序

#include<sys/socket.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<string.h>int main(){int sock=socket(AF_INET,SOCK_STREAM,0);struct sockaddr_in serv_addr;memset(&serv_addr,0,sizeof(serv_addr));serv_addr.sin_family=AF_INET;serv_addr.sin_addr.s_addr=inet_addr("127.0.0.1");serv_addr.sin_port=htons(9990);connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr));char message[30];read(sock,message,sizeof(message)-1);printf("%s\n",message);close(sock);return 0;
}

通俗版

 服务端程序

#include<sys/socket.h>
#include<arpa/inet.h>
#include<string.h>
int main(){//创建一台手机int serv_sock=socket(AF_INET,SOCK_STREAM,0);//创建一张电话卡struct sockaddr_in serv_addr;//运营商负责给电话卡填写信息memset(&serv_addr,0,sizeof(serv_addr));serv_addr.sin_family=AF_INET;serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);serv_addr.sin_port=htons(9990);//把电话卡插到手机里面bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr));//设置手机来电话时提醒listen(serv_sock,5);//再创建一张电话卡,用来存储打电话过来的手机的电话卡信息,比如手机号struct sockaddr_in clnt_addr;socklen_t clnt_addr_size=sizeof(clnt_addr);//如果有电话打来就把来电的电话卡信息存储到clnt_addr电话卡里面int clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_size);//按照clnt_addr电话卡的信息给这个来电的手机发送一个字符串"Hello"write(clnt_sock,"Hello",sizeof("Hello"));close(clnt_sock);close(serv_sock);return 0;
}

客户端程序

#include<sys/socket.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<string.h>int main(){//创建一部手机int sock=socket(AF_INET,SOCK_STREAM,0);//创建一张电话卡卡struct sockaddr_in serv_addr;//运营商负责填写电话卡信息memset(&serv_addr,0,sizeof(serv_addr));serv_addr.sin_family=AF_INET;serv_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//负责确定打给谁serv_addr.sin_port=htons(9990);//负责确定打给谁//拨打电话connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr));char message[30];//读取收到的"Hello"字符串read(sock,message,sizeof(message)-1);printf("%s\n",message);close(sock);return 0;
}

讲解版

服务端程序

#include<sys/socket.h>
#include<arpa/inet.h>
#include<string.h>
int main(){int serv_sock=socket(AF_INET,SOCK_STREAM,0);struct sockaddr_in serv_addr;memset(&serv_addr,0,sizeof(serv_addr));serv_addr.sin_family=AF_INET;serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);//INADDR_ANY表示可以接受来自任意IP地址的连接serv_addr.sin_port=htons(9990);//设置服务器端口号bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr));listen(serv_sock,5);struct sockaddr_in clnt_addr;socklen_t clnt_addr_size=sizeof(clnt_addr);int clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_size);write(clnt_sock,"Hello",sizeof("Hello"));close(clnt_sock);close(serv_sock);return 0;
}

为什么要设置服务器端口号?

端口号是一个16位的无符号整数,它可以唯一地标识服务器上的不同服务。

因为服务器在互联网中的IP地址是唯一的,但是服务器上运行着很多服务或者说程序,有的可能是用来处理web网页请求,有的可能是处理远程发来的数据库请求的。而由上面这个服务端代码建立的服务或者说程序只是服务器上众多服务或者说程序中的一个,那么当用本文的客户端代码创建的客户端程序通过IP地址找到这个服务器时,客户端程序怎么知道服务器上的运行着的数量众多的程序中哪个是用本文的服务端代码创建的服务端程序呢?通过设置具有唯一性的用来标识服务器上的不同服务的服务器端口号就能完美的解决这个问题,所以要设置服务器端口号。

进一步的说,用本文的客户端代码创建的客户端程序只要知道运行着用本文的服务端代码创建的服务端程序的服务器在互联网中的IP地址和这个服务端程序在服务器中的端口号,就能在茫茫的互联网中,精确的找到用本文的服务端代码创建的服务端程序。

在计算机网络中,客户端通过指定目标服务器的IP地址和端口号来与服务器建立连接。当客户端向服务器发送请求时,服务器会根据目标端口号识别请求,并将其路由到相应的服务程序。

通过设置端口号,可以使服务器上的不同服务在不同的端口上监听连接请求。这样,当客户端想要连接到特定的服务时,只需要指定相应的端口号即可。例如,Web服务器通常监听80端口,SMTP服务器通常监听25端口。

总而言之,设置服务器端口号是为了标识服务器上的不同服务,使客户端可以通过指定端口号与特定服务建立连接。

如果没有IP地址,怎么在互联网的几千万台计算机中,找到运行着用本文的服务端代码创建的服务端程序的计算机呢?如果没有端口,怎么在运行着众多程序的计算机中,用本文的服务端代码创建的服务端程序呢?

这就是为什么要设置端口和IP地址。

为什么不需要设置服务端的IP地址?

以后有空再写....

INADDR_ANY是什么意思?

INADDR_ANY表示可以接受来自任意IP地址的连接。

如果你把INADDR_ANY替换成成127.0.0.1,那么只会接收IP地址为127.0.0.1的客户端的连接请求

怎么获取到客户端的IP地址和端口号?

在上面的代码中,clnt_addr 是 sockaddr_in 类型的结构体,用于保存客户端的地址信息

accept函数会自动为我们填充 clnt_addr 结构体,其中包含:

  • clnt_addr.sin_addr.s_addr 客户端的IP地址
  • clnt_addr.sin_port 客户端的端口号

所以,在上面的代码中的accept函数下面添加如下代码就可以获取到客户端的IP地址和端口号:

char* ip = inet_ntoa(clnt_addr.sin_addr);
printf("Client IP: %s\n", ip);int port = ntohs(clnt_addr.sin_port);        
printf("Client port: %d\n", port);

值得注意的是,客户端程序的端口号和服务端设置的端口号是不一样的

怎么理解listen(serv_sock,5)?

通过设置 listen的第2个参数,可以控制连接队列中允许等待的最大连接数。如果连接队列已满,新的连接请求将被拒绝,直到有连接请求被处理并从队列中移出。

对于这个连接队列,我想说说自己的理解:

我认为连接队列在上面这个服务端程序是不可能满的,因为上面这个服务端程序没有创建新的线程或进程来处理连接请求。我认为只有使用了线程或者进程才可能会让连接队列满,之后有空的话,我会写一些程序来说明这个。

客户端程序

#include<sys/socket.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<string.h>int main(){int sock=socket(AF_INET,SOCK_STREAM,0);struct sockaddr_in serv_addr;memset(&serv_addr,0,sizeof(serv_addr));serv_addr.sin_family=AF_INET;serv_addr.sin_addr.s_addr=inet_addr("127.0.0.1"); //指明要连接的服务器的地址是什么serv_addr.sin_port=htons(9990);//指明要连接服务器的哪个端口connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr));char message[30];read(sock,message,sizeof(message)-1);printf("%s\n",message);close(sock);return 0;
}

这部分有空再更新....

相关文章:

编写一个最简单的Linux服务端和客户端程序

2023年8月3日&#xff0c;周四下午 这篇文章我从下午开始写了几个小时&#xff0c; 这篇文件基本总结了我今天学到的知识&#xff0c; 在写这篇文章的过程中灵感不断涌现、想明白了很多知识点&#xff0c;非常酣畅淋漓。 什么叫做深度学习&#xff1f;这就是深度学习&#…...

openKylin顺利加入RISC-V 基金会,推动架构芯片与操作系统协同发展

日前开放麒麟openKylin宣布&#xff0c;正式加入RISC-V基金会&#xff0c;由此成为其产业联盟成员。 公开资料显示&#xff0c;ISC-V是由加州大学伯克利分校研究团队在 2010年推出的一个开源指令集架构(ISA)。并且RISC-V拥有免费、高效、简洁和开放等特性qlbrsb。 作为新生的…...

SSM(Vue3+ElementPlus+Axios+SSM前后端分离)【二】

文章目录 SSM--基础环境搭建【二】项目介绍项目功能/界面● SSM 整合项目界面 项目全局配置web.xmlSpringMVC 配置 SSM–基础环境搭建【二】 项目介绍 项目功能/界面 ● SSM 整合项目界面 项目全局配置web.xml 配置furns_ssm\src\main\webapp\WEB-INF\web.xml , 和项目全局…...

出现一次的数字(其他数字出现三次,两次)

位运算的知识点&#xff1a; 异或运算具有以下几个重要性质 交换律&#xff1a;a ^ b b ^ a 结合律&#xff1a;a ^ (b ^ c) (a ^ b) ^ c 任何数与0异或等于它本身&#xff1a;a ^ 0 a 任何数与自身异或等于0&#xff1a;a ^ a 0 对于数组中所有元素进行异或运算&#xf…...

Rust- 智能指针

Smart pointers A smart pointer is a data structure that not only acts like a pointer but provides additional functionality. This “smartness” comes from the fact that smart pointers encapsulate additional logical or semantic rules, which are automaticall…...

什么是微服务

微服务的架构特征&#xff1a; 单一职责&#xff1a;微服务拆分粒度更小&#xff0c;每一个服务都对应唯一的业务能力&#xff0c;做到单一职责自治&#xff1a;团队独立、技术独立、数据独立&#xff0c;独立部署和交付面向服务&#xff1a;服务提供统一标准的接口&#xff0…...

无人机电力巡检方案在电网安全与维护中的应用

目前&#xff0c;无人机技术已经在各行各业都有广泛的应用&#xff0c;其中之一就是在电力巡检中的应用。无人机电力巡检方案以其高效、安全、精准的特点&#xff0c;为电网安全与维护带来了重大突破和进步。 一、无人机电力巡检方案是高效巡检的利器 传统的电力巡检方式需要人…...

网络工程师 快速入门

需要掌握 以下技术 1.网络 基础 知识 TCP/IP 、OSI 7层协议、IP地址、ARP地址解析协议、ICMP&#xff08;英特网控制报文协议&#xff0c;ping&#xff09;等 入门面试常问问题。 2.路由 路由匹配 三原则、静态路由、OSPF路由协议。 2.交换 如何放数据&#xff1f; VLAN TRU…...

Linux系统vim查看文件中文乱码

Linux系统查看文件-cat中文正常显示 vim中文乱码 1、背景2、环境3、目的4、原因5、操作步骤5.1、修改vim编码配置 6、验证 1、背景 服务器部署业务过程中查看文件内容&#xff0c;使用cat 命令查看中文正常显示&#xff0c;使用vim命令查看显示中文乱码 cat 查看 vim 查看 …...

BladeX框架开源-工作-笔记-Docker部署-Jenkins配置

BladeX框架开源-工作-笔记-Docker部署-Jenkins配置 文章目录 BladeX框架开源-工作-笔记-Docker部署-Jenkins配置第一章-概要-BladeX框架简介与git地址第二章-BladeX框架前后端项目Docker部署与DockerFile配置文件2.1-开始部署阶段&#xff0c;默认服务器上面已有Nacos服务2.2-采…...

Modbus tcp转ETHERCAT网关modbus tcp/ip协议

捷米JM-ECT-TCP网关能够连接到Modbus tcp总线和ETHERCAT总线中&#xff0c;实现两种不同协议设备之间的通讯。这个网关能够大大提高工业生产的效率和生产效益&#xff0c;让生产变得更加智能化。捷米JM-ECT-TCP 是自主研发的一款 ETHERCAT 从站功能的通讯网关。该产品主要功能是…...

RK356x Android11更换默认的Launcher

1、 开发环境 ubuntu版本&#xff1a;18.04 开发平台&#xff1a;RK356x Android版本&#xff1a;android11 2、目的 android11 系统自带了一个启动器Launcher3&#xff0c;在android源码路径下的packages/apps/Launcher3下&#xff0c;现需要将我们自己开发的Launcher放到a…...

Python 操作 MySQL 数据库

Python 操作 MySQL 数据库 Python 标准数据库接口为 Python DB-API&#xff0c;Python DB-API为开发人员提供了数据库应用编程接口。 Python 数据库接口支持非常多的数据库&#xff0c;你可以选择适合你项目的数据库&#xff1a; GadFlymSQLMySQLPostgreSQLMicrosoft SQL Se…...

脑电信号处理与特征提取——6.运用机器学习技术和脑电进行大脑解码(涂毅恒)

目录 六、运用机器学习技术和脑电进行大脑解码 6.1 前言 6.2 基于脑电数据的机器学习基础分析 6.3 基于脑电数据的机器学习进阶分析 6.4 代码解读 六、运用机器学习技术和脑电进行大脑解码 6.1 前言 6.2 基于脑电数据的机器学习基础分析 6.3 基于脑电数据的机器学习进阶分…...

腾讯云COS+PicGO+截图工具+Obsidian+Typora+蚁小二:打造丝滑稳定的Markdown写作和分发环境

背景 很久很久以前&#xff0c;我写过一篇《有道云笔记EverythingTyporaGitHub图床PicGojsDelivr加速截图工具——创造丝滑免费的Markdown写作环境》&#xff08;https://blog.csdn.net/qq_43721542/article/details/9685957&#xff09;&#xff0c;当时的目的是打造一个云同…...

LeetCode--HOT100题(18)

目录 题目描述&#xff1a;73. 矩阵置零&#xff08;中等&#xff09;题目接口解题思路1代码解题思路2代码 PS: 题目描述&#xff1a;73. 矩阵置零&#xff08;中等&#xff09; 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都…...

ES6的语法兼容IE浏览器

案例1 zdsxData.zdsxData.forEach(el>{let str <tr> <td><a href${el.url} target"_blank"><font color"#79EEFF">${el.sxms}</font></a></td> <td>${el.gjjd}</td> <td>${el.zrr}<…...

【opencv学习】鼠标回调函数、鼠标控制画矩形

#include <iostream> #include <opencv2/opencv.hpp> using namespace cv; #define WinDow "程序窗口"void MouseHandle(int event, int x, int y, int flags, void* param);//鼠标回调函数 void Drawrectangle(cv::Mat& img, cv::Rect box);//矩形绘…...

Typescript面试题

文章目录 了解过TS吗&#xff1f;使用ts写一个对象属性约束说一下typescript中的泛型如何在TS中对函数的返回值进行类型约束ts和js相比有什么区别 了解过TS吗&#xff1f; ts是一种基于静态类型检查的强类型语言 let num:number20 console.log(num) console.log("str&qu…...

GB28181智能安全帽方案探究及技术实现

什么是智能安全帽&#xff1f;​ 智能安全帽是一种集成先进科技的安全帽&#xff0c;可基于GB28181规范&#xff0c;适用于铁路巡检、电力、石油化工等高风险行业的作业人员&#xff0c;以及消防、救援等紧急情况下的安全防护。 智能安全帽通常具有以下功能&#xff1a; 实时…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...