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

Linux 网络编程 tcp server 笔记

一、TCP 服务器的创建

在 Linux 上创建一个简单的 tcp 服务器步骤如下:

①创建套接字

②将套接字绑定到 IP 地址和端口号

③监听来自客户端的连接

④接受连接并创建新的套接字用于与客户端通信

⑤通过新建的套接字发送和接收数据

⑥关闭套接字

流程框图如下:

7e06856095275adf66b6fb22f68a0c3b.png

根据以上介绍可以创建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;}

程序运行只允许单个客户端连接通讯。测试如下:

服务端启动,等待连接,如下:

50959d4753910442cafe7bf93bfb25fa.png

客户端连接,如下:

9c044a0cc3c0414d814cab194431c141.png

服务端获取到客户端连接,如下:

499390968ee107bb269ebe68b9b98bce.png

客户端发送数据,并接收到服务端返回,如下:

fe6c0bd29696559425a8169907429e7e.png

服务端显示:

bddbe154b449fa7b1c1eb62af765d2fc.png

三、服务器-多客户端

这里介绍两种方法,方法一:使用多线程;方法二:使用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;}

测试结果:

服务端:

2eedde70a977fc5d02db9ac76f735503.png

客户端:

5cf7c32b0cfbd080d17623fc87289453.png

相关文章:

Linux 网络编程 tcp server 笔记

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

C语言-贪吃蛇 1.输入控制ncurse

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

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版本。这个新驱动工作良好。但是&#xff0c;当打开MAX&#xff0c;NII MAQ设备却在RT PXI机箱里找不到。 问题最有可能是NIIMAQ服务器的版本跟主机PC和RT目标设备是不同的。为保证通信正常NII MAQ服…...

three.js入门 ---- 相机控件OrbitControls

前言&#xff1a; 自用&#xff01;&#xff01;&#xff01; 文档中描述&#xff1a;OrbitControls本质上就是改变相机的参数&#xff0c;比如相机的位置属性&#xff0c;改变相机位置可以改变相机拍照场景中模型的角度&#xff0c;实现模型的360度旋转预览效果&#xff0c;改…...

数字IC/FPGA面试题目合集解析(一)

数字IC/FPGA面试题目合集解析&#xff08;一&#xff09; 题目概述题目1&#xff0c;计算题2&#xff0c;计算题3&#xff0c;选择题 答案与解析1&#xff0c;计算题2&#xff0c;计算题3&#xff0c;选择题 题目概述 1&#xff0c;计算题&#xff1a;计算该触发器等效的建立保…...

20231014后台面经总结

1.Spring怎么解决循环依赖 形象地解释 为什么三层缓存 我的简单理解&#xff1a; 1.A依赖B&#xff0c;B生成时先注入A未注入属性的原始对象earlySingletonObject 2.引入三级缓存SingletonFacotry的目的是解决aop提前创建代理的步骤&#xff0c;不然它注入的对象跟真实的不一致…...

RabbitMQ的七种工作模式和分别概述

MQ&#xff08;Message Queuing&#xff09;的七种工作模式如下&#xff1a; Point-to-Point (P2P)模式&#xff1a;在这种模式下&#xff0c;消息传递是单向的&#xff0c;即消息从一个生产者发送到一个消费者。消息被放置在队列中&#xff0c;消费者从该队列中取出消息进行处…...

使用Vscode开发C#没有代码提示问题

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

统信UOS 1060上通过Fail2Ban来Ban IP

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

Linux系统编程:文件描述符以及IO多路复用

书接上回&#xff0c;我们之前学习的文件系统编程都是在内存空间中的文件流&#xff08;用户态文件缓冲区&#xff09;内进行操作的&#xff0c;比如使用的fopen、fclose、fread和fwrite等等都是库函数&#xff0c;并没有用到内核态的功能&#xff08;实际上库函数中调用的是内…...

python基于django的留学生服务管理平台

留学服务管理平台的用户是系统最根本使用者&#xff0c;按需要分析系统包括三类用户&#xff1a;学生、教师、管理员。这三类用户对系统的需求简要如下。技术栈 后端&#xff1a;pythondjango 前端&#xff1a;vueCSSJavaScriptjQueryelementui 开发语言&#xff1a;Python 框架…...

C++ 之 Map

Map map 是C STL中的关联容器&#xff0c; key-Value键值对存储&#xff0c;一对一的映射关系。 内部结构采用的是红黑树&#xff0c; 它会实现对数据的自动排序 &#xff0c;所以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是没有默认管理员账号&#xff0c;所以要先添加管理员账号…...

AndroidX项目接入穿山甲广告填坑

本文旨在记录初步接入过程遇到的一点点小问题&#xff0c;更详细的文档还是要参考官方文档。 一、项目版本 GradlePlugin&#xff1a;8.0.2 Gradle&#xff1a;8.0 Kotlin&#xff1a;1.7.20 compileSdk&#xff1a;34 compose-bom:2022.10.00 AS&#xff1a;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 往下拉&#xff0c;看到下载的链接 下载windows版本 下载地址&#xff1a; https://freefilesync.org/download/FreeFileSync_13.0_Windows_Setup.exe 直接复制到浏览器中访问就能下载 安装 双击安装包&#xff0c;一路默…...

【2023】M1/M2 Mac 导入Flac音频到Pr的终极解决方案

介绍 原作者链接&#xff1a;https://github.com/fnordware/AdobeOgg 很早之前就发现了这个插件&#xff0c;超级好用&#xff0c;在windows上完全没有问题&#xff0c;可惜移植到mac就不行了&#xff08;然后我给作者发了一个Issue&#xff0c;后来就有大佬把m1的编译出来了&…...

C# 图解教程 第5版 —— 第6章 方法

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

283 移动零

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

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

消息队列系统设计与实践全解析

文章目录 &#x1f680; 消息队列系统设计与实践全解析&#x1f50d; 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡&#x1f4a1; 权衡决策框架 1.3 运维复杂度评估&#x1f527; 运维成本降低策略 &#x1f3d7;️ 二、典型架构设计2.1 分布式事务最终一致…...

【Linux】Linux安装并配置RabbitMQ

目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的&#xff0c;需要先安…...