Linux 网络编程 tcp server 笔记
一、TCP 服务器的创建
在 Linux 上创建一个简单的 tcp 服务器步骤如下:
①创建套接字
②将套接字绑定到 IP 地址和端口号
③监听来自客户端的连接
④接受连接并创建新的套接字用于与客户端通信
⑤通过新建的套接字发送和接收数据
⑥关闭套接字
流程框图如下:
根据以上介绍可以创建tcp server的示例,分为服务器-单客户端和服务器-多客户端。
二、服务器-单客户端示例
tcp server示例代码如下:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> //struct sockaddr_in
#include <arpa/inet.h> //inet_addr()
#include <unistd.h>//close()#define MY_PRINTF(argv) do{\printf("file:%s --- function:%s --- line:%d\r\n",__FILE__,__FUNCTION__,__LINE__);\printf("%s\r\n",argv);\}while(0);
#define MYPORT 5000
//tcp server demoint main(int argc,char *argv[])
{int sockefd;int sockenewfd;int ret;int enable=1;struct sockaddr_in my_addr;//本地地址-服务器struct sockaddr_in remote_addr;//远端地址-客户端int remote_addr_len;char buf[1024];sockefd=socket(AF_INET,SOCK_STREAM,0);// 套接字if(sockefd<0){MY_PRINTF("socket err !! ");return -1;}if (setsockopt(sockefd, SOL_SOCKET, SO_REUSEADDR, (char *) &enable, sizeof(enable)) == -1) {close(sockefd);MY_PRINTF(" setsockopt err !! ");return -1;}MY_PRINTF("socket ok !! ");//本地地址my_addr.sin_family=AF_INET; my_addr.sin_port=htons(MYPORT);//0:随机端口my_addr.sin_addr.s_addr=INADDR_ANY;//inet_addr("192.168.164.157");//INADDR_ANY:本机 ip // inet_addr():IP 地址的字符串转换成一个无符号长整型bzero(my_addr.sin_zero,sizeof(my_addr.sin_zero));ret=bind(sockefd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr));//绑定 //转换数据类型if(ret<0){close(sockefd);MY_PRINTF("bind err !! ");return -1;}MY_PRINTF("bind ok !! ");ret=listen(sockefd,5);//监听if(ret<0){close(sockefd);MY_PRINTF("listen err !! ");return -1;}MY_PRINTF("listen ok !! ");sockenewfd=accept(sockefd,(struct sockaddr *)&remote_addr,&remote_addr_len);//获取连接的新套接字if(sockenewfd<0){close(sockefd);MY_PRINTF("accept err !! ");return -1;}MY_PRINTF("accept ok !! ");printf("%d\r\n",ntohs(remote_addr.sin_port)); //端口号printf("%s\r\n",inet_ntoa(remote_addr.sin_addr));//ip地址 //转换为字符串形式以 数字.数字.数字.数字 的格式显 示出来for(;;){ret=recv(sockenewfd,buf,sizeof(buf),0);//接收if(ret<0){close(sockenewfd);MY_PRINTF("recv err !! ");break;}else if(ret==0){close(sockenewfd);MY_PRINTF("close !! ");perror("close sockenewfd"); break;}MY_PRINTF("recv ok !! ");MY_PRINTF(buf);ret=send(sockenewfd,buf,ret,0);//发送 等价于write(sockenewfd,buf,ret);if(ret<0){MY_PRINTF("send err !! ");}MY_PRINTF("send ok !! ");MY_PRINTF(buf);}close(sockefd);//关闭perror("close sockefd");return0;}
程序运行只允许单个客户端连接通讯。测试如下:
服务端启动,等待连接,如下:
客户端连接,如下:
服务端获取到客户端连接,如下:
客户端发送数据,并接收到服务端返回,如下:
服务端显示:
三、服务器-多客户端
这里介绍两种方法,方法一:使用多线程;方法二:使用select方法。
①方法一多线程,测试代码如下:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> //struct sockaddr_in
#include <arpa/inet.h> //inet_addr()
#include <unistd.h>//close()#define MY_PRINTF(argv) do{\printf("file:%s --- function:%s --- line:%d\r\n",__FILE__,__FUNCTION__,__LINE__);\printf("%s\r\n",argv);\}while(0);
#define MYPORT 5000
//tcp server demovoid *myfun_thread(void *socketInfo)
{char buf[1024];int ret;int sockenewfd=(int)socketInfo;for(;;){ret=recv(sockenewfd,buf,sizeof(buf),0);//接收if(ret<0){close(sockenewfd);MY_PRINTF("recv err !! ");perror("close sockenewfd"); break;}else if(ret==0){close(sockenewfd);MY_PRINTF("close !! ");perror("close sockenewfd"); break;}MY_PRINTF("recv ok !! ");MY_PRINTF(buf);ret=send(sockenewfd,buf,ret,0);//发送 等价于write(sockenewfd,buf,ret);if(ret<0){MY_PRINTF("send err !! ");}MY_PRINTF("send ok !! ");MY_PRINTF(buf);}pthread_exit(NULL);}int main(int argc,char *argv[])
{int sockefd;int sockenewfd;int ret;int enable=1;pthread_t threadRx;struct sockaddr_in my_addr;//本地地址-服务器struct sockaddr_in remote_addr;//远端地址-客户端int remote_addr_len;sockefd=socket(AF_INET,SOCK_STREAM,0);// 套接字if(sockefd<0){MY_PRINTF("socket err !! ");return -1;}if (setsockopt(sockefd, SOL_SOCKET, SO_REUSEADDR, (char *) &enable, sizeof(enable)) == -1) {close(sockefd);MY_PRINTF(" setsockopt err !! ");return -1;}MY_PRINTF("socket ok !! ");//本地地址my_addr.sin_family=AF_INET; my_addr.sin_port=htons(MYPORT);//0:随机端口my_addr.sin_addr.s_addr=INADDR_ANY;//inet_addr("192.168.164.157");//INADDR_ANY:本机 ip // inet_addr():IP 地址的字符串转换成一个无符号长整型bzero(my_addr.sin_zero,sizeof(my_addr.sin_zero));ret=bind(sockefd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr));//绑定 //转换数据类型if(ret<0){close(sockefd);MY_PRINTF("bind err !! ");return -1;}MY_PRINTF("bind ok !! ");ret=listen(sockefd,5);//监听if(ret<0){close(sockefd);MY_PRINTF("listen err !! ");return -1;}MY_PRINTF("listen ok !! ");while(1){sockenewfd=accept(sockefd,(struct sockaddr *)&remote_addr,&remote_addr_len);//获取连接的新套接字if(sockenewfd<0){MY_PRINTF("accept err !! ");break;}MY_PRINTF("accept ok !! ");printf("%d\r\n",ntohs(remote_addr.sin_port)); //端口号printf("%s\r\n",inet_ntoa(remote_addr.sin_addr));//ip地址 //转换为字符串形式以 数字.数字.数字.数字 的格式显 示出来pthread_create(&threadRx, NULL, myfun_thread, (void *)sockenewfd);sleep(1);}close(sockefd);//关闭perror("close sockefd"); return 0;}
测试结果:
服务端:
客户端:
相关文章:

Linux 网络编程 tcp server 笔记
一、TCP 服务器的创建 在 Linux 上创建一个简单的 tcp 服务器步骤如下: ①创建套接字 ②将套接字绑定到 IP 地址和端口号 ③监听来自客户端的连接 ④接受连接并创建新的套接字用于与客户端通信 ⑤通过新建的套接字发送和接收数据 ⑥关闭套接字 流程框图如下…...

C语言-贪吃蛇 1.输入控制ncurse
一、为什么要用nurse C语言中的gets()、scanf()、getchar()等函数是在用户输入后需要按下Enter键才能执行代码,而贪吃蛇要求按下按键后立即对蛇的方向进行操作,所以根据贪吃蛇功能的需求引入ncurse,让用户输入后就能让蛇进行对应的行动。 二、…...

Pytorvh之Vision Transformer图像分类
文章目录 前言一、Transformer1.Transformer概览2.Self-Attention3.Multi-head Attention4.Position-wise Feed-Forward Networks(位置前馈网络)5.残差连接和层归一化6.Positional Encodings(位置编码) 二、Vision Transformer1.Vision Transformer概览2.Embedding层结构&#…...

LabVIEW为什么不能在RT机箱内看到NI-IMAQ设备
LabVIEW为什么不能在RT机箱内看到NI-IMAQ设备 最近把NI-IMAQ更新到最新的1394版本。这个新驱动工作良好。但是,当打开MAX,NII MAQ设备却在RT PXI机箱里找不到。 问题最有可能是NIIMAQ服务器的版本跟主机PC和RT目标设备是不同的。为保证通信正常NII MAQ服…...

three.js入门 ---- 相机控件OrbitControls
前言: 自用!!! 文档中描述:OrbitControls本质上就是改变相机的参数,比如相机的位置属性,改变相机位置可以改变相机拍照场景中模型的角度,实现模型的360度旋转预览效果,改…...

数字IC/FPGA面试题目合集解析(一)
数字IC/FPGA面试题目合集解析(一) 题目概述题目1,计算题2,计算题3,选择题 答案与解析1,计算题2,计算题3,选择题 题目概述 1,计算题:计算该触发器等效的建立保…...
20231014后台面经总结
1.Spring怎么解决循环依赖 形象地解释 为什么三层缓存 我的简单理解: 1.A依赖B,B生成时先注入A未注入属性的原始对象earlySingletonObject 2.引入三级缓存SingletonFacotry的目的是解决aop提前创建代理的步骤,不然它注入的对象跟真实的不一致…...
RabbitMQ的七种工作模式和分别概述
MQ(Message Queuing)的七种工作模式如下: Point-to-Point (P2P)模式:在这种模式下,消息传递是单向的,即消息从一个生产者发送到一个消费者。消息被放置在队列中,消费者从该队列中取出消息进行处…...

使用Vscode开发C#没有代码提示问题
很多小伙伴在使用Vscode去编写C#脚本的时候会发现没有代码提示,这样你的敲代码速度会变的很慢! 错误使用方法 直接把C#脚本拖入到Vscode中进行编写,这样是不会有代码提示的! 正确打开办式 Edit(编辑)…...

统信UOS 1060上通过Fail2Ban来Ban IP
原文链接:统信UOS 1060上通过Fail2Ban来Ban IP hello,大家好啊,今天给大家带来一篇在统信UOS 1060上安装Fail2Ban并且当ip被ban后通过邮件发送通知的文章。Fail2Ban 是一个用于防止暴力攻击的开源软件。它可以扫描日志文件(例如&a…...

Linux系统编程:文件描述符以及IO多路复用
书接上回,我们之前学习的文件系统编程都是在内存空间中的文件流(用户态文件缓冲区)内进行操作的,比如使用的fopen、fclose、fread和fwrite等等都是库函数,并没有用到内核态的功能(实际上库函数中调用的是内…...

python基于django的留学生服务管理平台
留学服务管理平台的用户是系统最根本使用者,按需要分析系统包括三类用户:学生、教师、管理员。这三类用户对系统的需求简要如下。技术栈 后端:pythondjango 前端:vueCSSJavaScriptjQueryelementui 开发语言:Python 框架…...
C++ 之 Map
Map map 是C STL中的关联容器, key-Value键值对存储,一对一的映射关系。 内部结构采用的是红黑树, 它会实现对数据的自动排序 ,所以map内部所有的数据都是有序的。 #include <map>定义的结构: map<数据类型1, 数据类型…...

MongoDB——centOS7环境Mongodb权限管理(图解版)
目录 一、MongDB权限概述1.1、MongDB权限概述1.2、MongDB权限列表 二、Mongodb权限管理示例2.1、创建账号2.1.1、创建管理员用户2.1.2、开启认证2.1.3、创建普通账号 一、MongDB权限概述 1.1、MongDB权限概述 mongodb是没有默认管理员账号,所以要先添加管理员账号…...
AndroidX项目接入穿山甲广告填坑
本文旨在记录初步接入过程遇到的一点点小问题,更详细的文档还是要参考官方文档。 一、项目版本 GradlePlugin:8.0.2 Gradle:8.0 Kotlin:1.7.20 compileSdk:34 compose-bom:2022.10.00 AS:2022.2.1 …...
汽车电子 - matlab - 用法
汽车电子 - matlab - 用法 面向对象 面向对象 % Man.m classdef Man < handle%UNTITLED2 此处显示有关此类的摘要% 此处显示详细说明properties(Accessprivate) %私有变量scoreendpropertiesageheightendmethodsfunction obj Man(inputArg1,inputArg2)%UNTITLED2 构造此…...

freefilesync文件同步软件
下载 下载链接 https://freefilesync.org/download.php 往下拉,看到下载的链接 下载windows版本 下载地址: https://freefilesync.org/download/FreeFileSync_13.0_Windows_Setup.exe 直接复制到浏览器中访问就能下载 安装 双击安装包,一路默…...

【2023】M1/M2 Mac 导入Flac音频到Pr的终极解决方案
介绍 原作者链接:https://github.com/fnordware/AdobeOgg 很早之前就发现了这个插件,超级好用,在windows上完全没有问题,可惜移植到mac就不行了(然后我给作者发了一个Issue,后来就有大佬把m1的编译出来了&…...

C# 图解教程 第5版 —— 第6章 方法
文章目录 6.1 方法的结构6.2 方法体内部的代码执行6.3 局部变量6.3.1 类型推断和 var 关键字6.3.2 嵌套块中的局部变量 6.4 局部常量6.5 控制流6.6 方法调用(*)6.7 返回值(*)6.8 返回语句和 void 方法6.9 局部函数6.10 参数&#…...

283 移动零
解题思路: \qquad 适用双指针,l:最左边‘0’元素坐标;r:l右边第一个非零元素坐标。 \qquad 最初的思路:将l和r初始化为0,遍历数组nums若任意一个指针到达数组末尾时停止。若当前nums[l] 0则移…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...

【记录坑点问题】IDEA运行:maven-resources-production:XX: OOM: Java heap space
问题:IDEA出现maven-resources-production:operation-service: java.lang.OutOfMemoryError: Java heap space 解决方案:将编译的堆内存增加一点 位置:设置setting-》构建菜单build-》编译器Complier...