当前位置: 首页 > 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则移…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...