linux下tcp/ip网络通信笔记1,

本文章主要为博主在学习网络通信的笔记+一个Udp_echo_server,和client的代码实现

1,网络发展,网络协议,意识到网络通信——不同主机的进程间通信,

2,学习如何在应用层调用系统提供的接口进行通信,echo_Udp_server, Udp_client,

目录

一,学的时候找别人的资源过一遍这些概念就好 

二,贴点代码,

InetAddr.hpp

common.hpp

Server.hpp

Server_main.cpp

Client_main.hpp

makefile



一,学的时候找别人的资源过一遍这些概念就好 

                以下个人理解,未必和发展历史相关,因果正确,博主建议概念性的知识你找别人看,博主的笔记仅仅为了给自己后期复习提醒一下,有些抽象和忽略,

发展/背景:局域网->广域网,主机数量变多,距离变远,各个要连接起来的局域网的协议不同,但却要组织起来进行通信,所以再次分层/包装->网络层,

下面列些概念性的,懒得往这里搬了,

1,纵向分层,横向模块

2,port端口号——主机在网络通信这块儿区别进程的标识符,

      Ip地址——主机在网络里的标识符,

      Mac地址——主机在局域网的标识符,

3,

      

 ​​​​​​​​​​​​​​

二,贴点代码,

博主在写的时候遇见最大的坑是ip转了两次(一次点分十进制转网络(inet_pton函数)一次在自己包装的inetaddr里也处理了一次(htonl函数)),导致出错, ,用到的系统调用的函数较少,代码量少,就这样了,跨过了/写过了,就觉得这echo_server和client也就那样,

InetAddr.hpp
#pragma once
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#include "common.hpp"
// 就把这个class当包装好的sockaddr_in用
// 主要是ip,port 本地转网络填socket, 网络转本地已经转好
class InetAddr{
private:void PortNet2Host(){ _port = ntohs(_addr.sin_port); }void IpNet2Host(){ char buf[64] = { 0 };const char* ip = inet_ntop(AF_INET, &_addr.sin_addr.s_addr, buf, sizeof(buf));_ip = ip; }
public:InetAddr(){memset(&_addr, 0, sizeof(_addr));}InetAddr(struct sockaddr_in& addr){   memset(&_addr, 0, sizeof(_addr));_addr.sin_family = addr.sin_family;_addr.sin_addr.s_addr = addr.sin_addr.s_addr;_addr.sin_port = addr.sin_port;Init();}InetAddr(uint32_t ip, uint16_t port){// ip = htonl(ip);port = htons(port);memset(&_addr, 0, sizeof(_addr));_addr.sin_family = AF_INET;_addr.sin_addr.s_addr = ip;_addr.sin_port = port;// 由_addr去设置_ip和_portInit();}InetAddr(uint16_t port){port = htons(port);memset(&_addr, 0, sizeof(_addr));_addr.sin_family = AF_INET;_addr.sin_addr.s_addr = INADDR_ANY;_addr.sin_port = port;Init();}void Init(){PortNet2Host();IpNet2Host();}struct sockaddr* Sockaddr_in(){ return CONV(&_addr); }socklen_t Socklen() { return sizeof(_addr); }std::string Ip(){ return _ip; }uint16_t Port(){ return _port; }~InetAddr(){}private:struct sockaddr_in _addr;std::string _ip = "";uint16_t _port = 0;
};
common.hpp
#pragma once#include <iostream>#define Die(code)   \do              \{               \exit(code); \} while (0)#define CONV(v) (struct sockaddr *)(v)enum 
{USAGE_ERR = 1,SOCKET_ERR,BIND_ERR,RECVFORM_ERR,SENDTO_ERR
};
Server.hpp
#pragma once
#include <iostream>
#include <functional>#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#include "InetAddr.hpp"
#include "common.hpp"
// ipv4 Udp EchoServer// 服务器需要,自己设置的port,ip写INADDR_ANY,
// 1 socket, 
// 2 bind
// 3 调用recvfrom()与sendto()开始通信
// 我需要设计一个class server, 给它指定的port,它能自己socket并bind, 要有start函数去使用recvfrom,sendto去通信
// 我还要一个class, 给它sockaddr_in, 它让我直接看到ip的点分十进制, 给它port, ip = INADDR_ANY,能吐出sockaddr_in.// server class == 一个运行的server, 
using func_t = std::function<std::string(const std::string&)>;
#define INIT_PORT 8080class UdpServer{
public:UdpServer(uint16_t port = INIT_PORT, func_t func = [](const std::string& s1){return s1;}):_addr(INADDR_ANY, port){_func = func;}void Init(){// 建文件描述符_sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(_sockfd < 0){Die(SOCKET_ERR);}if(bind(_sockfd, _addr.Sockaddr_in(), _addr.Socklen())){Die(BIND_ERR);}}void start(){_isrunning = true;std::cout << "start_server ~\n" << "wait client send messsge!" << std::endl;while(1){InetAddr client_sockaddr;char buf[1024] = { 0 };socklen_t size = client_sockaddr.Socklen();int n = recvfrom(_sockfd, buf, sizeof(buf) - 1, 0, client_sockaddr.Sockaddr_in(), &size);if(n < 0){Die(RECVFORM_ERR);}std::string s(buf);client_sockaddr.Init();std::cout << client_sockaddr.Ip() << ":" << client_sockaddr.Port() << ": " << s << std::endl;// s = _func(s);//n = sendto(_sockfd, s.c_str(), s.size(), 0, client_sockaddr.Sockaddr_in(), client_sockaddr.Socklen());if(n < 0){Die(SENDTO_ERR);}}_isrunning = false;}
private:int _sockfd = -1;InetAddr _addr; // 只存个自己的socketbool _isrunning = false; // 服务器运行状态// 业务func_t _func;
};
Server_main.cpp
#include "Server.hpp"
#include <functional>
#include <memory>
int main(int argc, char* argv[]){if(argc != 2){std::cout << "die~\n";Die(-1);}uint16_t port = atoi(argv[1]);std::unique_ptr<UdpServer> svr_uptr = std::make_unique<UdpServer>(port);svr_uptr->Init();std::cout << "Init_server ~\n";svr_uptr->start();return 0;
}
Client_main.hpp

#include <iostream>#include "common.hpp"
#include "InetAddr.hpp"int main(int argc, char* argv[]){if(argc != 3){exit(-1);}uint32_t ip = 0;inet_pton(AF_INET, argv[1], &ip);uint16_t port = atoi(argv[2]);InetAddr aim_server_addr(ip, port);int _fd = socket(AF_INET, SOCK_DGRAM, 0);while(1){std::cout << "Please Enter# " << std::endl;std::string s;socklen_t size = aim_server_addr.Socklen();std::getline(std::cin, s);int n = sendto(_fd, s.c_str(), s.size(), 0, aim_server_addr.Sockaddr_in(), aim_server_addr.Socklen());if(n < 0){Die(SENDTO_ERR);}std::cout << "sendto ed" << std::endl;std::cout << "sendto ed" << std::endl;std::cout << "sendto ed" << std::endl;std::cout << "sendto ed" << std::endl;std::cout << "sendto ed" << std::endl;std::cout << "sendto ed" << std::endl;char buf[1024] = { 0 }; n = recvfrom(_fd, buf, sizeof(buf) - 1, 0, aim_server_addr.Sockaddr_in(), &size);if(n > 0){buf[n] = 0;std::cout << buf << std::endl;}}return 0;
}
makefile
.PHONY:all
all:server_udp client_udpserver_udp:Server_main.cppg++ -o $@ $^ -std=c++17
client_udp:Client_main.cppg++ -o $@ $^ -std=c++17.PHONY:clean
clean:rm -f server_udp client_udp

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

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

相关文章

前端二进制数据指南:从 ArrayBuffer 到高级流处理

前端开发中&#xff0c;二进制数据是处理文件、图像、音视频、网络通信等场景的基础。以下是核心概念和用途的通俗解释&#xff1a; 前端二进制数据介绍 1. 什么是前端二进制数据&#xff1f; 指计算机原始的 0 和 1 格式的数据&#xff08;比如一张图片的底层代码&#xff…

Cacti 未经身份验证SQL注入漏洞

0x00 前言 Cacti是一套基于PHP,MySQL,SNMP及RRDTool开发的网络流量监测图形分析工具。 Cacti是通过 snmpget来获取数据&#xff0c;使用 RRDtool绘画图形&#xff0c;而且你完全可以不需要了解RRDtool复杂的参数。 0x01 漏洞描述 漏洞存在于从graph_view.php文件调用的growt…

使用国内源加速Qt在线安装

简介&#xff1a; 在线安装Qt时&#xff0c;会发现下载非常缓慢&#xff0c;可以用过使用国内镜像源来加速安装过程。 在线安装包的下载过程&#xff1a; 1&#xff0c;打开下载页面 https://www.qt.io/download-open-source 2&#xff0c;点击 Download the Qt online ins…

C#上位机RS485通信控制变频器

C#上位机使用Modbus RTU协议控制变频器 一、RTU报文格式示例 通信命令码&#xff1a; 03H:读从机参数 06H:写从机参数 10H:写多个参数上位机写单个寄存器&#xff1a;【从机地址】1字节【命令码】1字节【寄存器地址高-低】2字节【数据值高-低】2字节【CRC校验值低-高】…

OCC笔记:Brep格式

1. BREP格式简介 BREP格式是Open CASCADE内核&#xff08;OCCT&#xff09;的原生数据模型&#xff0c;直接描述几何体的边界表示&#xff08;面、边、顶点拓扑关系及几何参数&#xff09;。于OCCT内核的算法计算&#xff08;如布尔运算、曲面细分&#xff09;&#xff0c;存储…

Vue3进行工程化项目,保姆级教学(编译软件:vscode)大部分编译平台适用

目录 1. 创建vue工程 1.1 第一步 1.2 选择名称和工件 1.3 选择语言 1.4 自动下载js 1.5 运行vue工程 1.6 成功页面 2. 更改vue工程安装的位置 3. 更改运行工程方式 第一步 第二步 ​编辑 第三步 调试 ​编辑 运行项目 前面所学都是vue3的基础&#xff0c;为了简…

CSS常用选择器

CSS选择器用于选择HTML元素并为其应用样式。以下是CSS中最常用的选择器类型&#xff1a; 基本选择器 1.元素选择器 - 通过HTML标签名选择元素 p { color: blue; } 2.类选择器 - 通过class属性选择元素&#xff08;以.开头&#xff09; .warning { color: red; } 3.ID选择…

EmberGen导出序列图到UE5

选择Render节点 调整节点相关参数 然后选择一个目录 点击导出Export Now即可 材质用FlipBook 如果是特效就SubUV

EXCEL Python 实现绘制柱状线型组合图和树状图(包含数据透视表)

1、组合图、数据透视表 &#xff08;1&#xff09;数据预处理 知识点 日期函数 year() month()数据透视表操作 同比计算公式 环比计算公式 &#xff08;2&#xff09;excel 数据透视表插入组合图 a.2015~2017数据集处理方式&#xff1a; 操作&#xff1a; 结果 b.2020~20…

LabVIEW光谱检测系统

腔衰荡光谱技术&#xff08;CRDS&#xff09;凭借高精度和高灵敏度特性&#xff0c;成为微量气体浓度检测的常用方法&#xff0c;而准确获取衰荡时间是该技术应用的关键。基于LabVIEW平台设计腔衰荡信号在线处理系统&#xff0c;实现对衰荡信号的实时采集、平均、拟合、显示和保…

Flask快速入门和问答项目源码

Flask基础入门 源码&#xff1a; gitee&#xff1a;我爱白米饭/Flask问答项目 - 码云 目录 1.安装环境2.【debug、host、port】3.【路由params和query】4.【模板】5.【静态文件】6.【数据库连接】6.1.安装模块6.2.创建数据库并测试连接6.3.创建数据表6.4.ORM增删改查 6.5.ORM模…

flutter长列表 ListView、GridView、SingleChildScrollView、CustomScrollView区别

组件名称用途/适合场景是否懒加载支持列表结构用法复杂度SingleChildScrollView适用于内容数量不大、不重复的页面&#xff08;如表单、静态内容&#xff09;❌ 否❌ 否⭐⭐ListView适用于垂直方向的长列表&#xff0c;自动滚动&#xff1b;适合展示大量数据✅ 支持✅ 是⭐⭐Li…

鸿蒙OSUniApp 开发的一键分享功能#三方框架 #Uniapp

使用 UniApp 开发的一键分享功能 在移动应用开发中&#xff0c;分享功能几乎是必不可少的一环。一个好的分享体验不仅能带来更多用户&#xff0c;还能提升产品的曝光度。本文将详细讲解如何在 UniApp 框架下实现一个简单高效的一键分享功能&#xff0c;适配多个平台。 各平台分…

Vue-监听属性

监听属性 简单监听 点击切换名字&#xff0c;来回变更Tom/Jerry&#xff0c;输出 你好&#xff0c;Tom/Jerry 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>监听属性</title><!-- …

DeepSeek 赋能物联网:从连接到智能的跨越之路

目录 一、引言&#xff1a;物联网新时代的开启二、DeepSeek 技术揭秘2.1 DeepSeek 是什么2.2 DeepSeek 技术优势 三、DeepSeek 与物联网的融合之基3.1 物联网发展现状与挑战3.2 DeepSeek 带来的变革性突破 四、DeepSeek 在物联网的多元应用场景4.1 智慧电力&#xff1a;开启能源…

3.6/Q1,GBD数据库最新文章解读

文章题目&#xff1a;Global, regional, and national burden of geriatric depressive disorders in people aged 60 years and older: an analysis of the Global Burden of Disease Study 2021 DOI&#xff1a;10.1186/s12991-025-00560-2 中文标题&#xff1a;60 岁及以上人…

LVGL学习笔记

文章目录 一、 LVGL移植教程(GD32)一 并行驱动 LED二三一、 LVGL移植教程(GD32) 参考链接 1.GD32+LVGL移植教程(超详细)——基于GD32F303X系列MCU 一 并行驱动 LED 根据您提供的引脚信号(DCLK、DISP、HSYNC、VSYNC、DE),可以判断这是一款采用 TTL/Parallel RGB 接口…

软件架构之--论微服务的开发方法1

论微服务的开发方法1 摘要 2023年 2月,本人所在集团公司承接了长三角地区某省渔船图纸电子化审查系统项目开发,该项目旨在为长三角地区渔船建造设计院、以及渔船图纸审查机构提供一个便捷的渔船图纸电子化审查服务平台。在此项目中,我作为项目组成员参与项目的建设工作,并…

如何在终端/命令行中把PDF的每一页转换成图片(PNG)

今天被对象安排了一个任务&#xff1a; 之前自己其实也有这个需要&#xff0c;但是吧&#xff0c;我懒&#xff1a;量少拖拽&#xff0c;量大就放弃。但这次躲不过去了&#xff0c;所以研究了一下有什么工具可以做到这个需求。 本文记录我这次发现的使用 XpdfReader 的方法。…

mac安装cast

背景 pycharm本地运行脚本时提示cast没有安装 问题原因 脚本尝试调用cast命令&#xff08;以太坊开发工具foundry中的子命令&#xff09;&#xff0c;但您的系统未安装该工具。 从日志可见&#xff0c;错误发生在通过sysutil.py执行shell命令时。 解决方案 方法1&#xf…