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

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…...

恶补电源:1.电桥

一、元器件的选择 搜索并选择电桥&#xff0c;再multisim中选择FWB&#xff0c;就有各种型号的电桥: 电桥是用来干嘛的呢&#xff1f; 它是一个由四个二极管搭成的“桥梁”形状的电路&#xff0c;用来把交流电&#xff08;AC&#xff09;变成直流电&#xff08;DC&#xff09;。…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践

前言&#xff1a;本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中&#xff0c;跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南&#xff0c;你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案&#xff0c;并结合内网…...