【Linux】Linux下使用套接字进行网络编程
🔥博客主页: 我要成为C++领域大神
🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】
❤️感谢大家点赞👍收藏⭐评论✍️本博客致力于知识分享,与更多的人进行学习交流
用于网络应用开发,使用系统提供的一套API函数接口,称为套接字函数
所有的I/O设备都被抽象为文件,一切皆文件,Everything is a File,磁盘、网络数据、终端,甚至进程间通信工具管道pipe等都被当做文件对待。
套接字文件描述符包含有IP地址和PORT端口号。
socket创建套接字
函数原型:int sockfd=socket(AF_INET,SOCKET_STREAM(流式or报式),int protocol(默认流式协议TCP))
成功返回sock_fd,失败返回-1,并设置errno
bind绑定IP和端口
函数原型:bind(sock_fd,struct sockaddr *addr)
struct sockaddr *addr
是早期的网络通信结构体,为了向前兼容,仍然保留。
struct sockaddr_in addr
网络信息结构体
addr.sin_family=AF_INET
addr.sin_port=大端(8080)
addr.sin_addr.s_addr=大端(ip)
大小端转换常用函数
htons()
小端转大端端口
htonl()
小端转大端IP
ntohs()
大端转小端端口
ntohl()
大端转小端IP
inet_pton(AF_INET,char *ip,void *addr)
inet_ntop(AF_INET,void *addr,char *ip,16)
绑定可以对socket设置自定义的IP和端口号,其次当绑定某端口的进程退出,可以临时禁用端口号,禁用时长为2MSL。
成功返回0,失败返回-1
listen网络事件监听(TCP)
函数原型:listen(int sockfd,int backlog)
backlog:监听序列数
成功返回0,错误返回-1,并设置errno,用于错误处理
connet请求TCP连接函数(主动端)
函数原型:connect(int mysockfd,struct sockaddr * dest,socklen_t addrlen)
客户端调用该函数向服务器发起TCP连接请求
成功返回0,错误返回-1,并设置errno,用于错误处理
Accept等待TCP连接请求,完成连接(被动端)
Accept为阻塞等待连接,每次只能连接一个客户端,如果要多次连接,要执行多次该函数
函数原型:
int client_fd=accpet(int server_fd,sockaddr * clientAddr(output),socklen_t *Addrlen(intput|output))
arg[1] 包含自身网络信息的socket
arg[2] 连接成功,传出保存客户端的网络信息(IP,port)
arg[3] 传入可以接收的网络信息大小,传出实际大小
成功返回请求端的socketfd,错误返回-1,并设置errno,用于错误处理
CS架构中,服务器socket只有一个,客户端socket有多个(server_fd用于连接,client_fd用于与客户端交互数据)
recv读取数据
在Linux下,read也可以读取socket数据(TCP),因为在Linux下,套接字以文件描述符的形式记录。
函数原型:ssize_t recv(int sockfd,void *buf,size_t size,int flag)
成功返回读取的数据量,失败返回-1
可以通过将flag设置为MSG_DONTWAIT
实现非阻塞读取数据
send发送数据
在Linux下,write也可以发送socket数据(TCP),因为在Linux下,套接字以文件描述符的形式记录。
函数原型:ssize_t send(int sockfd,void *buf,size_t len,int flag)
面试题:
在编写一个服务端-客户端模型时,客户端异常退出,服务端也异常退出。
原因
当客户端异常退出时,客户端关闭了它的读端文件描述符。此时,如果服务端尝试向管道或套接字写数据,会触发 SIGPIPE
信号,默认行为是终止进程,因此服务端也会异常退出。
解决方案
可以在 send()
函数中使用 MSG_NOSIGNAL
标志位,来忽略 SIGPIPE
信号,从而避免服务端异常退出
send(int sockfd, buffer, len, MSG_NOSIGNAL);
使用 MSG_NOSIGNAL
标志位,写操作在对端关闭连接的情况下不会触发 SIGPIPE
信号,而是会返回 EPIPE
错误,程序可以根据这个错误码进行处理而不是直接终止。
在公网上利用TCP协议实现网络数据传输
由于服务端和客户端不在同一个局域网下,所以需要通过互联网进行通信,虚拟机要配置网络连接。
服务端:
服务端是运行在公网上的阿里云服务器。
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>#define _SERVER_IP "xxx.xxx.xxx.xxx"
#define _PORT 8080
#define _BACKLOG 128
#define _SHUTDOWN 1
#define _TRUE 1
#define _FALSE 0
#define _IPSIZE 16
#define _RECVLEN 1500int main()
{struct sockaddr_in serverAddr,clientAddr;int server_fd;int client_fd;char Result[_RECVLEN];char client_ip[_IPSIZE];socklen_t Addrlen;serverAddr.sin_family=AF_INET;serverAddr.sin_port=htons(_PORT);serverAddr.sin_addr.s_addr=htonl(INADDR_ANY);server_fd=socket(AF_INET,SOCK_STREAM,0);bind(server_fd,(struct sockaddr*)&serverAddr,sizeof(serverAddr));listen(server_fd,_BACKLOG);printf("Test TCP Server Version 1.1.0 is Running...\n");while(_SHUTDOWN){Addrlen=sizeof(clientAddr);if((client_fd=accept(server_fd,(struct sockaddr*)&clientAddr,&Addrlen))>0){bzero(Result,sizeof(Result));bzero(client_ip,sizeof(client_ip));inet_ntop(AF_INET,&clientAddr.sin_addr.s_addr,client_ip,_IPSIZE);printf("Connection From :IP[%s],PORT[%d]\n",client_ip,ntohs(clientAddr.sin_port));sprintf(Result,"Hi [%s] Welcome to my TCP test server!service version 1.1.0...",client_ip);send(client_fd,Result,strlen(Result),0);close(client_fd);}else{perror("accpet failed");close(server_fd);exit(0);}}close(server_fd);return 0;
}
客户端:
客户端是运行在本地上的虚拟机镜像
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>//客户端源码编写,连接服务器成功,服务器反馈信息#define _IP "xxx.xxx.xxx.xxx"
#define _PORT 8080
int main()
{struct sockaddr_in ServerAddr;bzero(&ServerAddr,sizeof(ServerAddr));ServerAddr.sin_family=AF_INET;ServerAddr.sin_port=htons(_PORT);inet_pton(AF_INET,_IP,&ServerAddr.sin_addr.s_addr);int Myfd=socket(AF_INET,SOCK_STREAM,0);//看需求决定是否要绑定char Response[1024];//存放服务端反馈信息ssize_t recvlen;bzero(Response,sizeof(Response));if((connect(Myfd,(struct sockaddr *)&ServerAddr,sizeof(ServerAddr)))==0){if((recvlen=recv(Myfd,Response,sizeof(Response),0))>0){printf("%s\n",Response);}}else{printf("Connect failed\n");close(Myfd);exit(0);}close(Myfd);printf("Client is Over\n");return 0;
}
运行结果:
函数二次包裹
在我们编写代码时,通常需要根据函数的返回值来判断函数调用情况,这个过程需要大量的if else语句,减少了代码阅读的简洁性。所以为了方便我们阅读,需要对函数进行二次包裹。
什么是二次包裹?
在自定义的头文件中重新声明一个函数,函数名与接口函数不同,返回值、参数均与接口函数相同。在相应的源文件中定义我们的函数,将逻辑判断的过程放在函数中。这样在调用函数时就省去大量的if else判断
#ifndef __MySock_H__
#define __MySock_H__
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>int SOCKET(int domain,int type,int protocol);
int BIND(int sockfd,struct sockaddr* addr,socklen_t addrlen);
ssize_t RECV(int sockfd,void *buf,size_t len,int flags);
ssize_t SEND(int sockfd,void *buf,size_t len,int flags);
int CONNECT(int sockfd,struct sockaddr *addr,socklen_t addrlen);
int ACCEPT(int sockfd,struct sockaddr *addr,socklen_t *addrlen);
int LISTEN(int sockfd,int backlog);#endif
#include "MySock.h"
int SOCKET(int domain,int type,int protocol)
{int reval=socket(domain,type,protocol); if(reval==-1){perror("socket call failed"); exit(0);}return reval;
}
int BIND(int sockfd,struct sockaddr* addr,socklen_t addrlen)
{int reval=bind(sockfd,addr,addrlen);if(reval==-1){perror("bind call failed");exit(0);}return reval;
}
ssize_t RECV(int sockfd,void *buf,size_t len,int flags)
{ssize_t reval;reval=recv(sockfd,buf,len,flags);if(reval==0)perror("recv call failed");return reval;
}
ssize_t SEND(int sockfd,void *buf,size_t len,int flags)
{ssize_t reval;reval=send(sockfd,buf,len,flags);if(reval==-1)perror("send call failed");return reval;
}
int CONNECT(int sockfd,struct sockaddr *addr,socklen_t addrlen)
{int reval=connect(sockfd,addr,addrlen);if(reval==-1){perror("connect call failed");exit(0);}return reval;
}int ACCEPT(int sockfd,struct sockaddr* addr,socklen_t *addrlen)
{int reval=accept(sockfd,addr,addrlen);if(reval==-1){perror("accept call failed");exit(0);}return reval;
}
int LISTEN(int sockfd,int backlog)
{int reval=listen(sockfd,backlog);if(reval==-1){perror("listen call failed");exit(0);}return reval;
}
使用包裹后的函数对我们TCP通信的客户端进行改写:
代码看起来简洁多了
#include "MySock.h"//客户端源码编写,连接服务器成功,服务器反馈信息#define _IP "xxx.xxx.xxx.xxx"
#define _PORT 8080
int main()
{struct sockaddr_in ServerAddr;bzero(&ServerAddr,sizeof(ServerAddr));ServerAddr.sin_family=AF_INET;ServerAddr.sin_port=htons(_PORT);inet_pton(AF_INET,_IP,&ServerAddr.sin_addr.s_addr);int Myfd=SOCKET(AF_INET,SOCK_STREAM,0);//看需求决定是否要绑定char Response[1024];//存放服务端反馈信息ssize_t recvlen;bzero(Response,sizeof(Response));if((CONNECT(Myfd,(struct sockaddr *)&ServerAddr,sizeof(ServerAddr)))==0){if((recvlen=recv(Myfd,Response,sizeof(Response),0))>0){printf("%s\n",Response);}}close(Myfd);printf("Client is Over\n");return 0;
}
相关文章:
【Linux】Linux下使用套接字进行网络编程
🔥博客主页: 我要成为C领域大神🎥系列专栏:【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 用于网络应用开…...
强化学习-Q-learning、SARSA和PPO等算法
强化学习 强化学习是一种机器学习方法,它关注智能体如何通过与环境的交互来最大化期望的累积奖励。在这个过程中,智能体不断尝试不同的行为策略,并根据结果调整策略,以提高长期的性能。以下是几种常见的强化学习算法:…...
HarmonyOS SDK助力鸿蒙原生应用“易感知、易理解、易操作”
6月21-23日,华为开发者大会(HDC 2024)盛大开幕。6月23日上午,《HarmonyOS开放能力,使能应用原生易用体验》分论坛成功举办,大会邀请了多位华为技术专家深度解读如何通过根技术、开放能力、场景化控件等亮点…...
Java基础入门day72
day72 mybatis mybatis的实现方式 三种实现方式: 纯xml方式,namespace随便写,id随便写,只要保证整个项目namespaceid唯一即可 xml接口的方式,namespace必须是接口的全路径,id必须是接口的方法名…...
文本编辑命令和正则表达式
一、 编辑文本的命令 正则表达式匹配的是文本内容,Linux的文本三剑客,都是针对文本内容。 文本三剑客 grep:过滤文本内容 sed:针对文本内容进行增删改查 (本文不相关) awk:按行取列 &#x…...
云手机群控功能讲解
接触云手机之前,很多企业或者个人卖家都对群控有浓厚的兴趣,云手机群控具体是什么呢?云手机群控,顾名思义,是指能够同时对多台云手机进行集中控制和管理的功能。打破了传统单台手机操作的限制,实现了规模化…...
gdb用法
创建文件 // main.cpp文件 // 稳态误差 void pid_test_wentaiwucha() {float p 1.5;int t 1; // t 1s;int target 5; // 5m/sfloat output 0;float radis 3; // 稳态误差std::cout << "output: " << std::endl;fo…...
聊一聊UDF/UDTF/UDAF是什么,开发要点及如何使用?
背景介绍 UDF来源于Hive,Hive可以允许用户编写自己定义的函数UDF,然后在查询中进行使用。星环Inceptor中的UDF开发规范与Hive相同,目前有3种UDF: A. UDF--以单个数据行为参数,输出单个数据行; UDF&#…...
配置Nginx二级域名
一、环境 (一)配置 1.服务器 linux CentOS 2.反向代理 Nginx 3.开放端口 云服务器开放端口80和443 二、域名备案 (一)腾讯云 1.腾讯云域名备案流程 备注:一级域名备案后,二级域名可以不用再备案&a…...
LeetCode——判断回文数
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 例如,121 是回文,而 …...
shell:使用结构化语句(for、while循环)
1. for命令 下面是bash shell中for命令的基本格式。 for var in list docommands done每次for命令遍历值列表,它都会将列表中的下个值赋给$test变量。$test变量可以像for 命令语句中的其他脚本变量一样使用。在最后一次迭代后,$test变量的值会在shell脚…...
数据结构_绪论
1.数据结构的研究内容 研究数据的特性和数据之间的关系 用计算机解决一个问题的步骤 1.具体问题抽象成数学模型 实质: 分析问题--->提取操作对象--->找出操作对象之间的关系(数据结构)--->用数学语言描述 操作对象对象之间的关系 2.设计算法 3.编程,调试,运行 …...
AI自动生成角色和情节连续的漫画,中山大学联想提出AutoStudio,可以多轮交互式连续生成并保持主题一致性。
中山大学和联想研究院提出AutoStudio: 是一种无需训练的多代理框架,用于多轮交互式图像生成,能够在生成多样化图像的同时保持主体一致性。 AutoStudio 采用三个基于 LLM 的智能体来解释人类意图并为 SD 模型生成适当的布局指导。此外,还引入…...
【经典面试题】RabbitMQ如何防止重复消费?
RabbitMQ的消息消费是有确认机制的,正常情况下,消费者在消费消息成功后,会发送一个确认消息,消息队列接收到之后,就会将该消息从消息队列中删除,下次也就不会再投递了。 但是如果存在网络延迟的问题&#…...
如何自己录制教学视频?零基础也能上手
随着在线教育的蓬勃发展,录制教学视频成为了教师和教育工作者们不可或缺的一项技能。无论是为了远程教学、课程分享还是知识普及,教学视频的录制都变得愈发重要。可是如何自己录制教学视频呢?本文将介绍两种录制教学视频的方法,这…...
【android】用 ExpandableListView 来实现 TreeView树形菜单视图
使用 ExpandableListView 来实现 TreeView 创建一个 ExpandableListAdapter 来为其提供数据。以下演示了如何使用 ExpandableListView 来展示树形结构的数据: 首先,在布局文件中添加 ExpandableListView: <ExpandableListViewandroid:i…...
策略模式与函数式编程应用
策略模式 | 单一职责原则(Single Responsibility Principle, SRP):islenone和islentwo分别根据特定条件返回电话号码 函数式编程: ‘’ if pd.isna(self.note1) else len(re.findall(r’\d, self.note1)) 重复代码: 当…...
docker原理记录C-N-A
docker原理 容器技术的兴起源于 PaaS 技术的普及 Docker 项目通过“容器镜像”,解决了应用打包这个根本性难题容器本身没有价值,有价值的是“容器编排”Cgroups 和 Namespace Cgroups 技术是用来制造约束的主要手段,而Namespace 技术则是用…...
【LeetCode】每日一题:二叉树的层次遍历
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 解题思路 水题 AC代码 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightN…...
单体架构改造为微服务架构之痛点解析
1.微服务职责划分之痛 1.1 痛点描述 微服务的难点在于无法对一些特定职责进行清晰划分,比如某个特定职责应该归属于服务A还是服务B? 1.2 为服务划分原则的痛点 1.2.1 根据存放主要数据的服务所在进行划分 比如一个能根据商品ID找出商品信息的接口,把…...
马面裙的故事:汉服如何通过直播电商实现产业跃迁
【潮汐商业评论/原创】 波澜壮阔的千里江山在马面裙的百褶上展开,织金花纹在女性的步伐之间若隐若现,从明清到现代,如今马面裙又流行了回来,成为女性的流行单品,2024年春节期间,马面裙更是成为华夏女孩们的…...
SaaS产品运营:维护四个不同类型的合作伙伴的实战指南
在SaaS(软件即服务)行业的竞争中,与合作伙伴建立并维护良好关系至关重要。不同类型的合作伙伴对于产品的推广、市场覆盖和用户增长都起着不同的作用。如何有效维护这四种类型合作伙伴?看个案例一起学习吧。 一、合作伙伴的四种类型…...
【监控】3.配置 Grafana 以使用 Prometheus 数据源
1 访问 Grafana 打开浏览器,访问 http://localhost:3000(默认端口)。使用默认的用户名和密码 admin/admin 登录。 2 添加 Prometheus 数据源 进入 Grafana 仪表板,点击左侧菜单中的“Configuration” -> “Data Sources”。…...
【LinuxC语言】网络编程中粘包问题
文章目录 前言什么叫做粘包问题粘包问题如何解决?总结前言 在进行网络编程时,我们经常会遇到一个非常常见但又往往被忽视的问题,那就是"粘包"问题。粘包是指在基于TCP/IP协议的数据传输过程中,由于TCP/IP协议是基于字节流的,这就可能会导致多个数据包被一起接收…...
Docker之jekins的安装
jekins官网地址:Jenkins Plugins (https://plugins.jenkins.io/) jekins 的docker 官方地址:https://hub.docker.com/r/jenkins/jenkins jekins 的docker 允许命令文档地址: docker/README.md at master jenkinsci…...
# bash: chkconfig: command not found 解决方法
bash: chkconfig: command not found 解决方法 一、chkconfig 错误描述: 这个错误表明在 Bash 环境下,尝试执行 chkconfig 命令,但是系统找不到这个命令。chkconfig 命令是一个用于管理 Linux 系统中服务的启动和停止的工具,通常…...
Linux线程互斥锁
目录 🚩看现象,说原因 🚩解决方案 🚩互斥锁 🚀关于互斥锁的理解 🚀关于原子性的理解 🚀如何理解加锁和解锁是原子的 🚩对互斥锁的简单封装 引言 大家有任何疑问,可…...
展开说说:Android列表之RecyclerView
RecyclerView 它是从Android5.0出现的全新列表组件,更加强大和灵活。用于显示列表形式 (list) 或者网格形式 (grid) 的数据,替代ListView和GridView成为Android主流的列表组件。可以说Android客户端只要有表格的地方就有RecyclerView。 RecyclerView 内…...
等保2.0时,最常见的挑战是什么?
等保2.0的常见挑战 等保2.0(网络安全等级保护2.0)是中国网络安全领域的基本制度,它对信息系统进行分级分类、安全保护和安全测评,以提高信息系统的安全性和可信性。在等保2.0的实施过程中,企业和组织面临多方面的挑战&…...
基于Vue 3.x与TypeScript的PPTIST本地部署与无公网IP远程演示文稿
文章目录 前言1. 本地安装PPTist2. PPTist 使用介绍3. 安装Cpolar内网穿透4. 配置公网地址5. 配置固定公网地址 前言 本文主要介绍如何在Windows系统环境本地部署开源在线演示文稿应用PPTist,并结合cpolar内网穿透工具实现随时随地远程访问与使用该项目。 PPTist …...
备案的网站做跳转不影响备案把/国内的搜索引擎有哪些
Java用OCI驱连Oracle数据库的实现方法来源:网络摘录 日期:2009-05-31 23:26 点击:0精华网络内容 :http://www.startajava.comJava程序连接oracle数据库时,用oci驱动要比用thin驱动性能好些。主要的区别是使用thin驱动时,不需要安装oracle的客户端&#x…...
网站静态与动态/seo点击软件手机
前言前面五篇文章,介绍了模型搭建、数据准备及pytorch中常用的计算方法等,有了上述基础后就可以训练和测试模型了,下面这篇文章会简单介绍下在pytorch框架下如何测试深度学习模型,以及一些常用代码。模型测试同样,以一…...
作一手房用什么做网站/seo竞价排名
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid3974 题意: 给你一个树,v,u 表示u是v的上司 有两个操作 1.让某一个点,和他的儿子们全部染成X 2.查询某一个点是什么颜色 题解: 当成图论跑一发,对于每一个查询直接跑到根…...
书店商城网站建设方案/百度怎么提交收录
假设consul软件安装在电脑ComputerA上,那么需要注册的服务ServiceA1也需要安装在电脑ComputerA上, 一个服务就是一个提供了ipport(或者域名)的应用程序。 服务: 服务: 1、服务名称:XXX。则生成的…...
网站搭建制作免费/百度广告收费表
// 借用构造函数// 其基本思路是在子类型构造函数的内部调用父类型的构造函数function Person(name){this.name name;this.friends ["Jack","John","Kim"];}function SuperPerson(name,sex){//继承PersonPerson.call(this,name);//call()将Per…...
wordpress 预览图/商品标题关键词优化
1、环境介绍 操作系统:centos 7.9 elasticsearch版本:7.13.3 2、生成es ca证书 bin/elasticsearch-certutil ca注意:提示输入密码:输入Smtgbk_123(自定义,后面配置文件中用到) 3、生成p12秘钥 bin/elasticsearch-…...