Linux高阶——1117—TCP客户端服务端
目录
1、sock.h
socket常用函数
网络初始化函数
首次响应函数
测试IO处理函数
获取时间函数
总代码
2、sock.c
SOCKET()
ACCEPT()——服务端使用这个函数等待客户端连接
CONNECT()——客户端使用这个函数连接服务端
BIND()——一般只有服务端使用
LISTEN()——服务端使用
RECV()
SEND()
net_initializer()——网络初始化函数
get_time()——获取时间函数
first_response()——首次适应函数
总代码
3、生成网络动态库
客户端代码
服务端代码
成功截图
1、sock.h
socket常用函数
int ACCEPT(int,struct sockaddr*,socklen_t *);
int SOCKET(int,int,int);
ssize_t RECV(int,void*,size_t,int);
int CONNECT(int, const struct sockaddr *,socklen_t);
int BIND(int, const struct sockaddr *,socklen_t);
int LISTEN(int, int backlog);
ssize_t SEND(int, const void *, size_t, int);
网络初始化函数
int net_initializer(const char*,int,int);
首次响应函数
int first_response(client_info);
测试IO处理函数
int test_business(int);
获取时间函数
int get_time(char* tm);
总代码
#ifndef _MYSOCK_
#define _MYSOCK_
#include<sys/socket.h>
#include<arpa/inet.h>
#include<string.h>
#include<netdb.h>
#include<errno.h>
#include<time.h>
#include<stdio.h>
#endiftypedef struct
{int sockfd;int port;char ip[16];
}client_info;int ACCEPT(int,struct sockaddr*,socklen_t *);
int SOCKET(int,int,int);
ssize_t RECV(int,void*,size_t,int);
int CONNECT(int, const struct sockaddr *,socklen_t);
int BIND(int, const struct sockaddr *,socklen_t);
int LISTEN(int, int backlog);
ssize_t SEND(int, const void *, size_t, int);int net_initializer(const char*,int,int);
int first_response(client_info);
int test_business(int);
int get_time(char* tm);
2、sock.c
SOCKET()
SOCKET(socket协议域,数据传输层使用协议模式,指定具体的协议)
int SOCKET(int domain,int type,int protocal)
{int fd; if((fd=socket(domain,type,protocal))==-1){perror("socket call failed");return fd; } return fd;
}
ACCEPT()——服务端使用这个函数等待客户端连接
ACCEPT(服务端socket,客户端的网络信息结构体,客户端网络信息结构体长度) ——客户端接收数据
int ACCEPT(int sockfd,struct sockaddr* addr,socklen_t * addrlen)
{int fd; if((fd=accept(sockfd,addr,addrlen))==-1){perror("accept call failed");return fd; } return fd;
}
CONNECT()——客户端使用这个函数连接服务端
客户端只有一个socket
CONNECT(用于连接的socket,目标信息结构体,目标信息结构体长度)
int CONNECT(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
{int fd;if((fd=connect(sockfd,addr,addrlen))==-1){perror("connect call failed");return fd;}return fd;
}
BIND()——一般只有服务端使用
BIND(需要绑定的socket,网络信息结构体的地址,网络信息结构体的长度)
int BIND(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
{int fd;if((fd=bind(sockfd,addr,addrlen))==-1){perror("bind call failed");return fd;}return fd;
}
LISTEN()——服务端使用
LISTEN(服务端socket,等待连接队列的最大长度)
int LISTEN(int sockfd, int backlog)
{int fd;if((fd=listen(sockfd, backlog))==-1){perror("listen call failed");return fd;}return fd;
}
RECV()
RECV(套接字sockfd,数据buf,数据长度size,选项,发送的长度)
对于服务端,sockfd是accept函数的返回值
对于客户端,sockfd是connect函数的返回值
ssize_t RECV(int sockfd,void* buf,size_t len,int flag)
{ssize_t fd; if((fd=recv(sockfd,buf,len,flag))==-1){perror("recv call failed");return fd; } return fd;
}
SEND()
SEND(发送的人的sockfd,数据buf,数据包长度)
ssize_t SEND(int sockfd, const void *buf, size_t len, int flags)
{ssize_t fd;if((fd=send(sockfd,buf,len,flags))==-1){perror("send call failed");return fd;}return fd;
}
net_initializer()——网络初始化函数
net_initializer(ip地址,端口号,可以监听队列的最大长度)
int net_initializer(const char* ip,int port,int backlog)
{int sockfd;struct sockaddr_in addr;bzero(&addr,sizeof(addr));addr.sin_family=AF_INET;addr.sin_port=htons(port);addr.sin_addr.s_addr=inet_addr("82.157.31.74");sockfd=SOCKET(AF_INET,SOCK_STREAM,0);BIND(sockfd,(struct sockaddr*)&addr,sizeof(addr));LISTEN(sockfd,backlog);return sockfd;
}
get_time()——获取时间函数
get_time(时间数组)
int get_time(char* tm)
{bzero(tm,1024);time_t tp;tp=time(NULL);ctime_r(&tp,tm);tm[strlen(tm)-1]='\0';return 0;
}
first_response()——首次适应函数
first_response(定义的结构体)
client_info——定义的结构体——包含port,ip,和创建的套接字
typedef struct
{int sockfd;int port;char ip[16];
}client_info;
int first_response(client_info cf)
{char response[1500];bzero(response,1500);char tm[1024];get_time(tm);printf("Server,output info,client ip %s,client port %d\n",cf.ip,cf.port);SEND(cf.sockfd,response,strlen(response),MSG_NOSIGNAL);return 0;
}
总代码
#include<sock.h>int ACCEPT(int sockfd,struct sockaddr* addr,socklen_t * addrlen)
{int fd; if((fd=accept(sockfd,addr,addrlen))==-1){perror("accept call failed");return fd; } return fd;
}int SOCKET(int domain,int type,int protocal)
{int fd; if((fd=socket(domain,type,protocal))==-1){perror("socket call failed");return fd; } return fd;
}ssize_t RECV(int sockfd,void* buf,size_t len,int flag)
{ssize_t fd; if((fd=recv(sockfd,buf,len,flag))==-1){perror("recv call failed");return fd; } return fd;
}int CONNECT(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
{int fd;if((fd=connect(sockfd,addr,addrlen))==-1){perror("connect call failed");return fd;}return fd;
}int BIND(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
{int fd;if((fd=bind(sockfd,addr,addrlen))==-1){perror("bind call failed");return fd;}return fd;
}int LISTEN(int sockfd, int backlog)
{int fd;if((fd=listen(sockfd, backlog))==-1){perror("listen call failed");return fd;}return fd;
}ssize_t SEND(int sockfd, const void *buf, size_t len, int flags)
{ssize_t fd;if((fd=send(sockfd,buf,len,flags))==-1){perror("send call failed");return fd;}return fd;
}int net_initializer(const char* ip,int port,int backlog)
{int sockfd;struct sockaddr_in addr;bzero(&addr,sizeof(addr));addr.sin_family=AF_INET;addr.sin_port=htons(port);addr.sin_addr.s_addr=inet_addr("82.157.31.74");sockfd=SOCKET(AF_INET,SOCK_STREAM,0);BIND(sockfd,(struct sockaddr*)&addr,sizeof(addr));LISTEN(sockfd,backlog);return sockfd;
}int get_time(char* tm)
{bzero(tm,1024);time_t tp;tp=time(NULL);ctime_r(&tp,tm);tm[strlen(tm)-1]='\0';return 0;
}int first_response(client_info cf)
{char response[1500];bzero(response,1500);char tm[1024];get_time(tm);printf("Server,output info,client ip %s,client port %d\n",cf.ip,cf.port);SEND(cf.sockfd,response,strlen(response),MSG_NOSIGNAL);return 0;
}
3、生成网络动态库
将所有的.c或.cpp变成可重定位二进制文件(载入库数据时,查找可用内存,而不是固定地址)
生成可重定位的二进制文件.o——gcc test.c -fPIC -I头文件路径 -c
gcc sock.c -I./ -fPIC -c
生成.so库——gcc xxx.o -shared -fPIC -I头文件 -o libmysock.so
共享库名,线程库里为-lpthread,内存中为libpthread.so
gcc sock.o -shared -fPIC -I./ -o libmysock.so
生成库后,需要使用-L指定库位置——gcc x.c -I头文件 -L 库路径 -lmysock -o app
如果共享库已经在默认/usr/lib位置,编译时无需-L参数
查看程序所依赖的库文件,查看未加载成功的库名——ldd 程序名
ldd app
将共享库.so文件复制到/usr/lib/——mv libname.so /usr/lib/
在linux操作系统下,使用ifconfig命令查看本机私有ip地址,如果本机写服务器使用本机ip
成功后,可以直接使用./程序名运行程序
客户端代码
#include<sys/socket.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>#define server_ip "192.168.5.133"
#define server_port 9090int main()
{struct sockaddr_in client_addr;bzero(&client_addr,sizeof(client_addr));client_addr.sin_family = AF_INET;client_addr.sin_port = htons(server_port);client_addr.sin_addr.s_addr = inet_addr(server_ip);inet_pton(AF_INET,server_ip,&client_addr.sin_addr.s_addr);int client_sock;if((client_sock=socket(AF_INET,SOCK_STREAM,0))==-1){ perror("sock create failed");return -1; } socklen_t addrlen;char recvv[1024];printf("TCP IO Client Running...\n");addrlen = sizeof(client_addr);if((connect(client_sock, (struct sockaddr*)&client_addr, addrlen))==-1){ perror("failed");return -1; } bzero(recvv,sizeof(recvv));printf("client sock %d\n",client_sock);int len=recv(client_sock,recvv,sizeof(recvv),0);if(len==-1)perror("recv call failed");printf("len %d %s\n",len, recvv);close(client_sock);
}
服务端代码
#include<sock.c>
#define server_ip "192.168.5.133"
#define server_port 9090int main()
{struct sockaddr_in client_addr;int server_sock;int client_sock;server_sock=net_initializer(NULL,server_port,128);socklen_t addrlen;printf("TCP IO Servers Running...\n");char cip[16];ssize_t len;client_info cf;char buf[1500];char* msg="Please try again\n";char tm[1024];while(1){addrlen=sizeof(client_addr);client_sock=ACCEPT(server_sock,(struct sockaddr*)&client_addr,&addrlen);cf.sockfd=client_sock;inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,cf.ip,16);cf.port=ntohs(client_addr.sin_port);first_response(cf);while((len=RECV(client_sock,buf,sizeof(buf),0))>0){if((strcmp(buf,"time\n"))==0){get_time(tm);SEND(client_sock,tm,strlen(tm),MSG_NOSIGNAL);bzero(tm,sizeof(tm));}else{SEND(client_sock,msg,strlen(msg),MSG_NOSIGNAL);}bzero(buf,sizeof(buf));}if(len==0){printf("client exit\n");close(client_sock);}}close(server_sock);printf("server done\n");return 0;
}
成功截图
相关文章:

Linux高阶——1117—TCP客户端服务端
目录 1、sock.h socket常用函数 网络初始化函数 首次响应函数 测试IO处理函数 获取时间函数 总代码 2、sock.c SOCKET() ACCEPT()——服务端使用这个函数等待客户端连接 CONNECT()——客户端使用这个函数连接服务端 BIND()——一般只有服务端使用 LISTEN()——服务端…...
【Qt】Qt 在main.cpp中使用tr()函数报错
1. 问题 Qt 在main.cpp中使用tr()报错。 error: tr was not declared in this scope2. 解决方法 main.cpp中注意如下: //添加头文件 #include <QObject>//添加QObject QObject::tr("Hello")3. 参考 Qt tr()函数不起效的小问题...
面向对象高级(5)接口
面向对象高级(5) 接口 接口就是规范,定义的是一组规则,体现了现实世界中“如果是...则必须能...”的思想。继承是一个"是不是"的is-a关系,而接口实现则是 "能不能"的has-a关系。 1、接口的定义格…...

uniapp发布android上架应用商店权限
先看效果: 实现原理: 一、利用uni.addInterceptor的拦截器,在一些调用系统权限前拦截,进行弹窗展示,监听确定取消实现业务逻辑。 二、弹窗是原生nativeObj进行drawRect绘制的 三、权限申请调用使用的 plus.android.…...

Centos Stream 9安装Jenkins-2.485 构建自动化项目步骤
官网:https://www.jenkins.io/ 1 下载 环境准备: 版本支持查询:https://pkg.jenkins.io/redhat-stable/ 安装JDK17:https://blog.csdn.net/qq_44870331/article/details/140784297 yum -y install epel-release wget upgradew…...

电路模型和电路定理(二)
电路元件 是电路中最基本的组成单元。 电阻元件:表示消耗电能的元件 电感元件:表示产生磁场,储存磁场能的元件 电容元件:表示产生电场,储存电场能量的元件 电压源和电流源:表示将其他形式的能量转变成…...

瑞佑液晶控制芯片RA6807系列介绍 (三)软件代码详解 Part.10(让PNG图片动起来)完结篇
RA6807是RA8876M的缩小版,具备RA8876M的所有功能,只将MCU控制接口进行缩减,仅保留SPI-3和I2C接口,其它功能基本相同。 该芯片最大可控制854x600的分辨率,内建64Mbits显存,多个图层,使用起来相当…...

Qt常用控件 按钮
文章目录 1. QAbstractButton 简介2. QPushButton2.1 例子1,设置按钮的图标2.2 例子2,设置按钮快捷键 3. QRadioButton3.1 介绍3.2 例子1,选择性别3.3 例子2,试试其他的信号3.3 例子3,分组 4. QCheckBox4.1 介绍4.2 例…...

MySQL学习/复习10视图/用户/权限/语言连接数据库
一、视图 1.1创建视图 1.2视图影响基表 1.3基表影响视图 1.4删除视图 1.5视图使用规则 二、数据库的用户 2.1mysql中的user表 注意事项:主机/用户名/密码/权限 2.2用户的创建 注意事项:设置密码与登录地点需谨慎 2.3删除用户 注意事项:% 2.4…...

vulfocus在线靶场:tomcat-pass-getshell 弱口令 速通手册
目录 一、启动环境,访问页面,并登录,账号密码都是tomcat 二、哥斯拉打war包,图解 三、上传war包,图解 四、访问我们直接url/木马文件名/木马文件.jsp,是否存在了 五、 哥斯拉测试连接结果success&…...

c#:winform调用bartender实现打印(学习整理笔记)
效果 学习路径 C# winform调用Bartender进行自定义打印、批量打印、检索文件夹中的模板_哔哩哔哩_bilibili 一、初始环境搭建见: c#:winform引入bartender-CSDN博客https://blog.csdn.net/weixin_46001736/article/details/143989473?sharetypeblogdetail&s…...
牛客题库 21738 牛牛与数组
牛牛与数组题目链接 题目大意 牛牛喜欢这样的数组: 1:长度为n 2:每一个数都在1到k之间 3:对于任意连续的两个数A,B,A<=B 与(A % B != 0) 两个条件至少成立一个请问一共有多少满足条件的数组,对 1 e 9 + 7 1e^9+7 1e9+7 取模 输入格式 输入两个整数 n , k n,k n,…...

探索PDFMiner:Python中的PDF解析利器
文章目录 **探索PDFMiner:Python中的PDF解析利器**1. 背景介绍:为何选择PDFMiner?2. PDFMiner是什么?3. 如何安装PDFMiner?4. 简单库函数使用方法4.1 提取文本4.2 获取页面布局信息4.3 提取表格数据4.4 提取图像 5. 应…...
掌握Go语言中的异常控制:panic、recover和defer的深度解析
掌握Go语言中的异常控制:panic、recover和defer的深度解析 在Go语言的编程世界中,异常处理是一个不可忽视的话题。Go语言提供了panic、recover和defer三个关键字来处理程序中的异常情况。本文将深入探讨这三个关键字的工作原理、使用场景和最佳实践,帮助读者在实际编程中更…...

云讷科技Kerloud无人飞车专利发布
云讷科技Kerloud无人飞车获得了“一种室内外两用的四旋翼无人飞车”的实用新型专利证书,作为科教社区第一款四旋翼飞车,这项技术结合了无人机和无人车的优势,提供了一种能够在多种环境下使用的多功能飞行器。 这项设计的优势如下ÿ…...

企业信息化-走进身份管理之搭建篇
一、身份管理是什么 我们先要弄懂统一身份管理到底是什么? 统一身份管理(Unified Identity Manager,UIM),身份管理(Identity Management,简称IDM),也被称为IAM&#…...

实践指南:EdgeOne与HAI的梦幻联动
在当今快速发展的数字时代,安全和速度已成为网络服务的基石。EdgeOne,作为腾讯云提供的边缘安全加速平台,以其全球部署的节点和强大的安全防护功能,为用户提供了稳定而高效的网络体验。而HAI(HyperApplicationInventor…...

Exploring Prompt Engineering: A Systematic Review with SWOT Analysis
文章目录 题目摘要简介方法论背景相关工作评估结论 题目 探索快速工程:基于 SWOT 分析的系统评价 论文地址: https://arxiv.org/abs/2410.12843 摘要 在本文中,我们对大型语言模型 (LLM) 领域的提示工程技术进行了全面的 SWOT 分析。我们强…...
ByteBuffer 与 ByteBuf 的对比与优缺点分析
在 Java 网络编程和高性能 I/O 场景中,ByteBuffer 和 ByteBuf 是两种重要的缓冲区处理工具。ByteBuffer 是 Java NIO 标准库的一部分,而 ByteBuf 是由 Netty 框架提供的增强缓冲区工具。在实际开发中,选择哪一种取决于场景需求和性能目标。 …...

js高级06-ajax封装和跨域
8.1、ajax简介及相关知识 8.1.1、原生ajax 8.1.1.1、AJAX 简介 AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML。 通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。 按需请求,可…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...

C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...