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

Linux下,基于TCP与UDP协议,不同进程下单线程通信服务器

C语言实现Linux下,基于TCP与UDP协议,不同进程下单线程通信服务器

一、TCP单线程通信服务器

  • 先运行server端,再运行client端
  • 输入"exit" 是退出

1.1 server_TCP.c

**#include <my_head.h>#define PORT 6666
#define IP "192.168.125.103"int main(int argc, const char *argv[])
{//  创建流式套接字int server_fd = socket(AF_INET, SOCK_STREAM, 0);if (server_fd < 0){ERR_MSG("socket");return -1;}printf("套接字创建成功 server_fd = %d\n", server_fd);//  允许端口快速复用int reuse = 1;if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){ERR_MSG("setsockopt");return -1;}printf("允许端口快速复用成功\n");//  绑定服务器的地址信息    必须绑定struct sockaddr_in server_in;              //  用于绑定本主机的信息server_in.sin_family = AF_INET;            //  必须填 AF_INET//  因为前面创建流式套接字用的是 IPv4server_in.sin_port = htons(PORT);          //  指定端口号server_in.sin_addr.s_addr = inet_addr(IP); //  绑定本机IPif (bind(server_fd, (struct sockaddr *)&server_in, sizeof(server_in)) < 0){ERR_MSG("bin");return -1;}printf("bind 成功\n");//  将套接字转换为被动监听状态if (listen(server_fd, 256) < 0){ERR_MSG("listen");return -1;}printf("listen 成功\n");//  获取连接成功的客户端信息,生成一个新的文件描述符//  该文件描述符才是与客户端通信的文件描述符struct sockaddr_in client_in;                                             //  用于存放接收的客户端的信息socklen_t addrlen = sizeof(client_in);                                    //  用于存放客户端传来的信息的长度int new_fd = accept(server_fd, (struct sockaddr *)&client_in, &addrlen); //  连接客户端if (new_fd < 0){ERR_MSG("accept");return -1;}printf("new_fd = %d    __%d__\n", new_fd, __LINE__);//  输出客户端IP和端口号printf("client IP = %s\n", inet_ntoa(client_in.sin_addr));printf("client port = %d\n", ntohs(client_in.sin_port));//  接收数据char buff[128];ssize_t res = 0;while (1){//  清空暂存区bzero(buff, sizeof(buff));//  接收数据    当最后一个参数为 0 时,也可以用 read// res = recv(new_fd, buff, sizeof(buff), 0);res = read(new_fd, buff, sizeof(buff));if (res < 0){ERR_MSG("recv");return -1;}//  写端关闭了,即客户端关闭else if (0 == res){printf("[ %s : %d ]客户端断开链接\n", inet_ntoa(client_in.sin_addr),ntohs(client_in.sin_port));break;}//  输出客户端信息 和 接收的数据printf("[ %s : %d ] [massage : %s ]\n", inet_ntoa(client_in.sin_addr),ntohs(client_in.sin_port), buff);//  接收的数据为 退出 (exit)if (!strcmp(buff, "exit")){printf("已断开\n");break;}//  发送数据//  向客户端发送消息printf("回复:");scanf("%s", buff);if (!strcmp(buff, "exit")){printf("已断开\n");break;}//  发送if (send(new_fd, buff, sizeof(buff), 0) < 0){ERR_MSG("send");return -1;}printf("buff = %s\n", buff);putchar(10);}//  关闭套接字close(server_fd);close(new_fd);return 0;
}

1.2 client_TCP.c

#include <my_head.h>#define SERVER_PORT 6666            //  服务器端口号
#define SERVER_IP "192.168.125.103" //  服务器IPint main(int argc, const char *argv[])
{//  创建客户端流式套接字int client_fd = socket(AF_INET, SOCK_STREAM, 0);if (client_fd < 0){ERR_MSG("socket");return -1;}printf("套接字创建成功 client_fd = %d\n", client_fd);//  端口快速复用int reuse = 1;if (setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){ERR_MSG("setsockopt");return -1;}printf("允许端口快速复用成功\n");//  绑定客户端信息,非必须绑定,建议不绑//  如果不绑定,操作系统会自动分配端口号//  连接服务器struct sockaddr_in server_in;server_in.sin_addr.s_addr = inet_addr(SERVER_IP);server_in.sin_port = htons(SERVER_PORT);server_in.sin_family = AF_INET;//  连接if (connect(client_fd, (struct sockaddr *)&server_in, sizeof(server_in)) < 0){ERR_MSG("connect");return -1;}char buff[128];ssize_t res = 0;while (1){//  发送消息printf("请输入 : ");fgets(buff, sizeof(buff), stdin);buff[strlen(buff) - 1] = 0;if (send(client_fd, buff, sizeof(buff), 0) < 0){ERR_MSG("send");return -1;}if (!strcmp(buff, "exit")){printf("断开链接\n");break;}printf("发送成功\n");bzero(buff, sizeof(buff));//  接收消息res = recv(client_fd, buff, sizeof(buff), 0);if (res < 0){ERR_MSG("recv");return -1;}else if (0 == res){printf("[ %s : %d ] 服务器断开链接   __%d__\n", SERVER_IP, SERVER_PORT, __LINE__);break;}printf("[ %s : %d ] [massage : %s ]\n", SERVER_IP, SERVER_PORT, buff);}close(client_fd);return 0;
}

二、TCP单线程通信服务器

  • 先运行server端,再运行client端
  • 输入"exit" 是退出

2.1 server_UDP.c

#include <my_head.h>#define SERVER_PORT 6666
#define SERVER_IP "192.168.125.103"int main(int argc, const char *argv[])
{//  创建报式套接字int client_fd = socket(AF_INET, SOCK_DGRAM, 0);if (client_fd < 0){ERR_MSG("socket");return -1;}printf("套接字创建成功 client_fd = %d\n", client_fd);//  允许端口快速复用int reuse = 1;if (setsockopt(client_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){ERR_MSG("setsockopt");return -1;}printf("允许端口快速复用成功\n");//  绑定客户端信息,非必须绑定,建议不绑//  如果不绑定,操作系统会自动分配端口号//  指定服务器的信息struct sockaddr_in server_addr;                     //  用于绑定本主机的信息server_addr.sin_family = AF_INET;                   //  必须填 AF_INET//  因为前面创建报式套接字用的是 IPv4server_addr.sin_port = htons(SERVER_PORT);          //  指定端口号server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); //  绑定本机IP//  发送数据char buff[128];ssize_t res = 0;struct sockaddr_in client_addr;socklen_t client_len = sizeof(client_addr);while (1){//  清空暂存区bzero(buff, sizeof(buff));//  发送数据//  向客户端发送消息printf("请输入 : ");scanf("%s", buff);//  发送if (sendto(client_fd, buff, sizeof(buff), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){ERR_MSG("sendto");return -1;}if (!strcmp(buff, "exit")){printf("已断开\n");break;}printf("buff = %s\n", buff);//  接收数据    当最后一个参数为 0 时,也可以用 read// res = recv(client_fd, buff, sizeof(buff), 0);// res = read(client_fd, buff, sizeof(buff));res = recvfrom(client_fd, buff, sizeof(buff), 0, (struct sockaddr *)&client_addr, &client_len);if (res < 0){ERR_MSG("recv");return -1;}//  输出客户端信息 和 接收的数据printf("[ %s : %d ] [massage : %s ]\n", inet_ntoa(client_addr.sin_addr),htons(client_addr.sin_port), buff);//  接收的数据为 退出 (exit)if (!strcmp(buff, "exit")){printf("已断开\n");break;}putchar(10);}//  关闭套接字close(client_fd);return 0;
}

2.2 client_UDP.c

#include <my_head.h>#define PORT 6666
#define IP "192.168.125.103"int main(int argc, const char *argv[])
{//  创建报式套接字int server_fd = socket(AF_INET, SOCK_DGRAM, 0);if (server_fd < 0){ERR_MSG("socket");return -1;}printf("套接字创建成功 server_fd = %d\n", server_fd);//  允许端口快速复用int reuse = 1;if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0){ERR_MSG("setsockopt");return -1;}printf("允许端口快速复用成功\n");//  绑定服务器的地址信息    必须绑定struct sockaddr_in server_in;              //  用于绑定本主机的信息server_in.sin_family = AF_INET;            //  必须填 AF_INET//  因为前面创建报式套接字用的是 IPv4server_in.sin_port = htons(PORT);          //  指定端口号server_in.sin_addr.s_addr = inet_addr(IP); //  绑定本机IP//  绑定if (bind(server_fd, (struct sockaddr *)&server_in, sizeof(server_in)) < 0){ERR_MSG("bind");return -1;}printf("bind 成功\n");//  UDP不用连接,所以也不用监听//  接收数据char buff[128];ssize_t res = 0;struct sockaddr_in client_addr;socklen_t client_len = sizeof(client_addr);while (1){//  清空暂存区bzero(buff, sizeof(buff));//  接收数据    当最后一个参数为 0 时,也可以用 read// res = recv(new_fd, buff, sizeof(buff), 0);// res = read(server_fd, buff, sizeof(buff));res = recvfrom(server_fd, buff, sizeof(buff), 0, (struct sockaddr *)&client_addr, &client_len);if (res < 0){ERR_MSG("recvfrom");return -1;}//  输出客户端信息 和 接收的数据printf("[ %s : %d ] [massage : %s ]\n", inet_ntoa(client_addr.sin_addr),htons(client_addr.sin_port), buff);//  接收的数据为 退出 (exit)if (!strcmp(buff, "exit")){printf("已断开\n");break;}//  发送数据//  向客户端发送消息printf("回复:");scanf("%s", buff);if (!strcmp(buff, "exit")){printf("已断开\n");break;}//  发送if (sendto(server_fd, buff, sizeof(buff), 0, (struct sockaddr *)&client_addr, client_len) < 0){ERR_MSG("sendto");return -1;}printf("buff = %s\n", buff);putchar(10);}//  关闭套接字close(server_fd);return 0;
}

相关文章:

Linux下,基于TCP与UDP协议,不同进程下单线程通信服务器

C语言实现Linux下&#xff0c;基于TCP与UDP协议&#xff0c;不同进程下单线程通信服务器 一、TCP单线程通信服务器 先运行server端&#xff0c;再运行client端输入"exit" 是退出 1.1 server_TCP.c **#include <my_head.h>#define PORT 6666 #define IP &qu…...

qt功能自己创作

按钮按下三秒禁用 void MainWindow::on_pushButton_5_clicked(){// 锁定界面setWidgetsEnabled(ui->centralwidget, false);// 创建一个定时器&#xff0c;等待3秒后解锁界面QTimer::singleShot(3000, this, []() {setWidgetsEnabled(ui->centralwidget, true);;//ui-&g…...

Linux网络编程:使用UDP和TCP协议实现网络通信

目录 一. 端口号的概念 二. 对于UDP和TCP协议的认识 三. 网络字节序 3.1 字节序的概念 3.2 网络通信中的字节序 3.3 本地地址格式和网络地址格式 四. socket编程的常用函数 4.1 sockaddr结构体 4.2 socket编程常见函数的功能和使用方法 五. UDP协议实现网络通信 5.…...

【后端速成 Vue】初识指令(上)

前言&#xff1a; Vue 会根据不同的指令&#xff0c;针对标签实现不同的功能。 在 Vue 中&#xff0c;指定就是带有 v- 前缀 的特殊 标签属性&#xff0c;比如&#xff1a; <div v-htmlstr> </div> 这里问题就来了&#xff0c;既然 Vue 会更具不同的指令&#…...

爬虫 — Scrapy-Redis

目录 一、背景1、数据库的发展历史2、NoSQL 和 SQL 数据库的比较 二、Redis1、特性2、作用3、应用场景4、用法5、安装及启动6、Redis 数据库简单使用7、Redis 常用五大数据类型7.1 Redis-String7.2 Redis-List (单值多value)7.3 Redis-Hash7.4 Redis-Set (不重复的)7.5 Redis-Z…...

tcpdump常用命令

需要安装 tcpdump wireshark ifconfig找到网卡名称 eth0, ens192... tcpdump需要root权限 网卡eth0 经过221.231.92.240:80的流量写入到http.cap tcpdump -i eth0 host 221.231.92.240 and port 80 -vvv -w http.cap ssh登录到主机查看排除ssh 22端口的报文 tcpdump -i …...

计算机网络运输层网络层补充

1 CDMA是码分多路复用技术 和CMSA不是一个东西 UPD是只确保发送 但是接收端收到之后(使用检验和校验 除了检验的部分相加 对比检验和是否相等。如果不相同就丢弃。 复用和分用是发生在上层和下层的问题。通过比如时分多路复用 频分多路复用等。TCP IP 应用层的IO多路复用。网…...

java CAS详解(深入源码剖析)

CAS是什么 CAS是compare and swap的缩写&#xff0c;即我们所说的比较交换。该操作的作用就是保证数据一致性、操作原子性。 cas是一种基于锁的操作&#xff0c;而且是乐观锁。在java中锁分为乐观锁和悲观锁。悲观锁是将资源锁住&#xff0c;等之前获得锁的线程释放锁之后&am…...

1786_MTALAB代码生成把通用函数生成独立文件

全部学习汇总&#xff1a; GitHub - GreyZhang/g_matlab: MATLAB once used to be my daily tool. After many years when I go back and read my old learning notes I felt maybe I still need it in the future. So, start this repo to keep some of my old learning notes…...

2023/09/19 qt day3

头文件 #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QDebug> #include <QTime> #include <QTimer> #include <QPushButton> #include <QTextEdit> #include <QLineEdit> #include <QLabel> #include &l…...

Docker 学习总结(78)—— Docker Rootless 让你的容器更安全

前言 在以 root 用户身份运行 Docker 会带来一些潜在的危害和安全风险,这些风险包括: 容器逃逸:如果一个容器以 root 权限运行,并且它包含了漏洞或者被攻击者滥用,那么攻击者可能会成功逃出容器,并在宿主系统上执行恶意操作。这会导致宿主系统的安全性受到威胁。 特权升…...

如何使用ArcGIS Pro将等高线转DEM

通常情况下&#xff0c;我们拿到的等高线数据一般都是CAD格式&#xff0c;如果要制作三维地形模型&#xff0c;使用栅格格式的DEM数据是更好的选择&#xff0c;这里就为大家介绍一下如何使用ArcGIS Pro将等高线转DEM&#xff0c;希望能对你有所帮助。 创建TIN 在工具箱中选择“…...

【爬虫基础】万字长文详解XPath

1. 引言 XPath&#xff08;XML Path Language&#xff09;是一种在XML和HTML文档中查找和定位信息的强大工具。XPath的重要性在于它允许我们以简洁而灵活的方式导航和选择文档中的元素和属性。本文将深入介绍XPath的基础知识&#xff0c;帮助你掌握这个强大的查询语言&#xf…...

分布式多级缓存SDK设计的思考

分布式多级缓存SDK设计的思考 背景整体架构多层级组装回调埋点分区处理一致性问题缓存与数据库之间的一致性问题不同层级缓存之间的一致性问题不同微服务实例上&#xff0c;非共享缓存之间的一致性问题 小结 之前实习期间编写过一个简单的多级缓存SDK&#xff0c;后面了解到一些…...

设计模式:适配器模式(C++实现)

适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构设计模式&#xff0c;它允许将一个类的接口转换成客户端所期望的另一个接口。适配器模式通常用于连接两个不兼容的接口或类&#xff0c;使它们能够一起工作。 以下是一个简单的C适配器模式的示例&#xff1a; #in…...

【深度学习实验】前馈神经网络(二):使用PyTorch实现不同激活函数(logistic、tanh、relu、leaky_relu)

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. 定义激活函数 logistic(z) tanh(z) relu(z) leaky_relu(z, gamma0.1) 2. 定义输入、权重、偏置 3. 计算净活性值 4. 绘制激活函数的图像 5. 应用激活函数并…...

容器技术所涉及Linux内核关键技术

一、容器技术前世今生 1.1 1979年 — chroot 容器技术的概念可以追溯到1979年的UNIX chroot。 它是一套“UNIX操作系统”系统&#xff0c;旨在将其root目录及其它子目录变更至文件系统内的新位置&#xff0c;且只接受特定进程的访问。 这项功能的设计目的在于为每个进程提供…...

IPV4和IPV6,公网IP和私有IP有什么区别?

文章目录 1、什么是IP地址&#xff1f;1.1、背景1.2、交换机1.3、局域网1.4、广域网1.5、ISP 互联网服务提供商 2、IPV42.1、什么是IPV4&#xff1f;2.2、IPV4的组成2.3、NAT 网络地址转换2.4、端口映射 3、公网IP和私有IP4、IPV6 1、什么是IP地址&#xff1f; 1.1、背景 一台…...

高云FPGA系列教程(7):ARM GPIO外部中断

文章目录 [toc]GPIO中断简介FPGA配置常用函数MCU程序设计工程下载 本文是高云FPGA系列教程的第7篇文章。 本篇文章介绍片上ARM Cortex-M3硬核处理器GPIO外部的使用&#xff0c;演示按键中断方式来控制LED亮灭&#xff0c;基于TangNano 4K开发板。 参考文档&#xff1a;Gowin_E…...

Python爬虫:动态获取页面

动态网站根据用户的某些操作产生一些结果。例如&#xff0c;当网页仅在向下滚动或将鼠标移动到屏幕上时才完全加载时&#xff0c;这背后一定有一些动态编程。当您将鼠标指针悬停在某些文本上时&#xff0c;它会为您提供一些选项&#xff0c;它还包含一些动态.这是是一篇关于动态…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...