用C++写一个简单的服务器(Linux)

2023-05-16

用C++写一个简单的服务器(Linux)

下面是创建一个简单服务器的基本流程,所用的端口是8099。后面贴了代码。

一、基本流程:

  1. 创建套接字
  2. 配置服务器地址相关参数
  3. 将两者绑定
  4. 监听套接字上的端口
  5. 在上面创建的套接字上等待连接,并打开一个新的套接字用于与请求之间的交互
  6. 在发送缓冲区中写入响应
  7. 关闭连接
  1. 创建套接字
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(listenfd < 0){
    std::cout << "create socketfd failed" <<std::endl;
    return 0;
}

函数socket()所在的头文件sys/socket.h,声明为
extern int socket (int __domain, int __type, int __protocol) __THROW;

  1. 配置服务器地址相关参数
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);

变量servaddr类型struct sockaddr_in,它所在的头文件netinet/in.h

  1. 将上面两者绑定
int bind_ok = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
if(bind_ok < 0){
    std::cout << "bind socket with server address  failed" <<std::endl;
    return 0;
}

函数bind()所在的头文件sys/socket.h,声明为
extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len) __THROW;

  1. 监听套接字上的端口
int listen_ok = listen(listenfd, LISTENQ);
if(listen_ok < 0){
    std::cout << "listen socket  failed" <<std::endl;
    return 0;
}

函数listen()所在的头文件sys/socket.h,声明为
extern int listen (int __fd, int __n) __THROW;

  1. 在上面创建的套接字上等待连接,并打开一个新的套接字用于与请求之间的交互
connfd = accept(listenfd, NULL, NULL);
if(connfd < 0){
    std::cout << "create connection socket failed" <<std::endl;
    return 0;
}

函数accept()所在的头文件sys/socket.h,声明为
extern int accept (int __fd, __SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len);

  1. 在发送缓冲区中写入响应
write_ok = write(connfd, buffer.c_str(), strlen(buffer.c_str()));
if(write_ok < 0){
    std::cout << "write info to connection socket failed" <<std::endl;
    close(connfd);
    return 0;
}

函数 write()所在的头文件unistd.h,声明为
extern ssize_t write (int __fd, const void *__buf, size_t __n) __wur;

函数close()所在的头文件unistd.h,声明为
extern int close (int __fd);

  1. 关闭连接
close(connfd);

二、编译、运行、验证

$ # 编译
$ g++ simple_server.cpp -o run_this
$ # 运行
$ ./run_this
$ # 打开一个新的shell窗口,然后执行下面的命令
$ curl http://localhost:8099
$ # 执行后,新的shell窗口会有如下的显示结果:
hello, this is a simple server.
$ # 运行 run_this 的窗口中,当服务器接收到请求之后,会显示如下的结果:
hello, this is a simple server.

length of it: 32

三、代码

#include <iostream>     // std::cout、std::endl
#include <sys/socket.h> // socket、bind、listen、accept
#include <netinet/in.h> // htonl、htons
#include <unistd.h>     // write、close
#include <string.h>     // bzero
#define PORT 8099
#define LISTENQ 5
int main(){
    /* 准备重要参数 */
    // 结构体 sockaddr_in 位于 netinet/in.h
    int listenfd, connfd;
    struct sockaddr_in servaddr;
    
    /* 创建套接字 */
    // 常量 AF_INET 位于 bits/socket.h,经由 sys/socket.h 导入
    // 常量 SOCK_STREAM 位于 bits/socket_type.h,先后经由 bits/socket.h、sys/socket.h 导入
    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if(listenfd < 0){
        std::cout << "create socketfd failed" <<std::endl;
        return 0;
    }

    /* 准备地址端口信息 */
    // 常量 INADDR_ANY 位于 netinet/in.h
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(PORT);
    
    /* 绑定套接字与地址端口 */
    int bind_ok = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    if(bind_ok < 0){
        std::cout << "bind socket with server address  failed" <<std::endl;
        return 0;
    }
    
    /* 监听端口 */
    int listen_ok = listen(listenfd, LISTENQ);
    if(listen_ok < 0){
        std::cout << "listen socket  failed" <<std::endl;
        return 0;
    }
    
    /* 准备这个简单服务器返回的信息 */
    std::string buffer = "hello, this is a simple server.\n";
    int write_ok; // 用于判断是否成功将数据写入发送缓存
    // 循环等待
    while(1){
    	// 监听到有请求,创建交互的套接字
        connfd = accept(listenfd, NULL, NULL);
        if(connfd < 0){
            std::cout << "create connection socket failed" <<std::endl;
            return 0;
        }
        std::cout << buffer << std::endl << "length of it: " << buffer.size()<< std::endl;
        
        // 将响应的数据写入发送缓冲区
        write_ok = write(connfd, buffer.c_str(), strlen(buffer.c_str()));
        if(write_ok < 0){
            std::cout << "write info to connection socket failed" <<std::endl;
            close(connfd); // 关闭连接
            return 0;
        }
        // 关闭连接
        close(connfd);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用C++写一个简单的服务器(Linux) 的相关文章

  • 【数据结构】树

    一 树 1 什么是树 xff1f 树状图是一种数据结构 xff0c 它是由n xff08 n gt 61 1 xff09 个有限节点组成一个具有层次关系的集合 把它叫做 树 是因为它看起来像一棵倒挂的树 xff0c 也就是说它是根朝上 xf
  • 【专题2: 嵌入式stm32】 之 【6.中断和异常】

    嵌入式工程师成长之路 系列文章 总目录系列文章总目录希望本是无所谓有 xff0c 无所谓无的 xff0c 这正如脚下的路 xff0c 其实地上本没有路 xff0c 走的人多了 xff0c 也便成了路原创不易 xff0c 文章会持续更新 xf
  • workerman-chat启动失败解决办法

    该教程是在官方文档的基础上再加上本人的踩坑经验进行的优化 在开始搭建环境之前 xff0c 先要确认你要搭建聊天室的站点的PHP版本 xff0c 为什么要确认PHP版本 xff1f 等下会解释 下面以PHP5 6为例 1 环境检测 官网方法
  • oracle 分区和面向对象数据库系统的学习

    在过去的一周里面 xff0c 学习了oracle表分区 xff0c object relational database system简介 1 oracle分区 oracle分区是在oracle 8 0中引入的 xff0c 这个过程是将一个
  • 非线性系统线性化过程

    线性化 在对非线性系统进行建模分析时 xff0c 对模型进行线性化处理可以简化分析过程 例子 xff1a 磁悬浮系统建模 系统非线性模型 xff1a m a 61 m g k f i z 2 m a 61 m g
  • ECMAScript 6学习笔记(六)数组的扩展

    数组的扩展 1 扩展运算符 含义 扩展运算符 xff08 spread xff09 是三个点 xff08 xff09 它好比 rest 参数的逆运算 xff0c 将一个数组转为用逗号分隔的参数序列 该运算符主要用于函数调用 span cla
  • vs2022 x64 C/C++和汇编混编

    vs2022环境x64 C C 43 43 和汇编混编 vs64位程序不支持 asm内嵌汇编 xff0c 需要单独编写汇编源文件示例如下1 新建空的win32项目 xff0c 新建main cpp xff0c 示例代码如下2 新建asm64
  • python学习:解决如何在函数内处理数据而不影响原列表

    python学习 xff1a 解决如何在函数内处理数据而不影响原列表 关于一个如何在函数内修改三阶矩阵 在python里 xff0c 如果想要定义一个函数 xff0c 把列表当c 43 43 里的形参传进去 xff0c 显然是不可能的 在p
  • 有关树莓派驱动1.3寸IPS屏幕的一点经验

    有关树莓派驱动1 3寸IPS屏幕的经验 前言CS引脚按键显示效果 后记 分享最近我用树莓派驱动IPS屏幕及微雪1 3inch LCD HAT的经验 前言 我的树莓派zero w已经吃灰很久了 xff0c 趁着今年电赛留校集训期间玩一玩 注意
  • tensorflow采坑系列-InvalidArgumentError: Shape [-1,784] has negative dimensions

    问题描述 xff1a InvalidArgumentError Traceback most recent call last d span class hljs command Anaconda span 3 span class hlj
  • 在旧版本Ubuntu系统中使用“apt-get update”出现“404 Not Found”错误的解决办法

    每一个Ubuntu发布版本都有它的结束时间 xff0c 通常 xff0c Ubuntu发布版本支持18个月 xff0c 而LTS Long Term Support xff08 长期支持 xff09 版本分别支持3年 服务器版 和5年 桌面
  • 使用 ROS中的插件

    URDF 文件完成后 xff0c 可以在 rviz 中显示机器人的模型 xff0c 如果要在 gazebo 中进行物理环境仿真 xff0c 还需要为 URDF 文件加入一些 gazebo 相关的标签 既然是仿真 xff0c 那么机器人应该像
  • linux杀毒软件

    0x00前言 linux或者Unix系统经常被用作服务器 xff0c 并且安全性往往比windows高 xff0c 但是在linux查杀病毒往往得依靠管理员执行find grep等命令查看文件以确认文件是否为病毒 xff0c 但由于本身li
  • 使用LVM对根分区进行扩容

    使用LVM对根分区进行扩容 1 df h 查看当前根分区大小 可以看到我们当前根分区的大小为66G 2 创建PV物理卷 pvcreate span class token operator span dev span class token
  • 毕业了,投入的工作

    2012年7月1日 xff0c 一个全新的开始 大学毕业了 xff0c 结束了学生时代 xff0c 走向社会 xff0c 开始工作 开始挣钱 xff0c 在一个熟悉的城市里 xff0c 面对陌生的面孔 使用未曾听过见过的语言 xff0c 技
  • vscode配置git

    首先下载git 下载完成后复制git路径 xff0c 如 xff1a D Software Git cmd git exe 也可以打开cmd窗口输入 where git 然后打开vscode xff0c 打开设置 xff0c 搜索git p
  • STM32的printf函数重定向

    在前面学习了STM32的串口编程 xff0c 通过USART1向计算机的串口调试助手打印数据 xff0c 或者接收计算机串口调试助手的数据 xff0c 接下来我们可以实现STM32工程上的printf 函数了 xff0c 方便用于程序开发中
  • 【opencv学习】【轮廓检测】

    今天学习轮廓检测方法 span class token keyword import span cv2 span class token keyword import span numpy span class token keyword
  • Jetson Xavier NX下读取RTSP视频流

    现有一个网络摄像机 xff0c 需要在Jetson Xavier NX平台上读取它的视频流进行图像处理 xff0c 最基本的使用Opencv读取RTSP视频流代码如下 xff1a span class token keyword impor
  • 化繁为简,一张图看懂梯度、散度、旋度、Jacobian、Hessian和Laplacian

    点击上方 计算机视觉工坊 xff0c 选择 星标 干货第一时间送达 作者 xff5c 王赟 Maigo 64 知乎 xff08 已授权 xff09 来源 xff5c https zhuanlan zhihu com p 35323714 编

随机推荐

  • 一文详解PnP算法原理

    PnP Perspective n Point 问题的几何结构如图1所示 xff0c 给定3D点的坐标 对应2D点坐标以及内参矩阵 xff0c 求解相机的位姿 数学语言描述如下 xff1a 图1 PnP几何结构 1 直接线性变换法 Dire
  • 多传感器数据标定融合完整教程:时间同步+空间同步(Camera+Lidar+IMU+Radar)

    多传感器融合是一项结合多传感器数据的综合性前沿内容 xff0c 主要包括Camera 激光雷达 IMU 毫米波雷达等传感器的融合 xff0c 在自动驾驶 移动机器人的感知和定位领域中占有非常重要的地位 xff1b 随着AI技术的大规模落地
  • 机器人抓取—— 相机参数与标定 camera_calibration

    点击上方 计算机视觉工坊 xff0c 选择 星标 干货第一时间送达 整理丨古月居 相机的参数 参考 xff1a https blog csdn net weixin 43206570 article details 84797361 摄像机
  • ROS下面调用自定义的头文件和.cpp/.so文件(亲测有效)

    前言 ROS下面使用已经编译好的ROS package是很方便的 xff0c 但是大多数我们可能自己定义了一些头文件 xff0c 想去直接引用 xff0c 那么如何在ROS下面调用自己的定义的函数呢 xff1f ROS下调用自定义的头文件
  • catkin_make和cmake

    catkin make是ROS下面的一种编译方式 xff0c 基于cmake xff0c 但是又不同于cmake cmake只能编译指定的package xff0c 但是不同package之间的关系没办法链接 xff0c 而且cmake只能
  • UNIX date命令简介

    date 命令 参数含义 xff1a a xff1a 显示星期简写 Sun Sat A xff1a 显示完整星期 Sunday Saturday b xff1a 显示月份简写 Jan Dec B xff1a 显示完整月份 January D
  • NVIDIA JETSON XAVIER NX烧录(emmc版本)

    目录 0 前言 1 安装虚拟机 2 安装SDKManager 3 使用SDK Manager开始烧录 4 配置系统 5 开发环境的安装 xff08 CUDA xff09 6 遇到问题记录 xff08 如果有其它问题可以留言我补充 xff09
  • NVIDIA JETSON XAVIER NX烧录(sd版本)

    0 前言 本文主要补充上文提到的sd卡版本烧录Jetson Xavier Nx系统的 xff0c 需要准备的东西 一张空白SD卡balenaEtcher工具 JETSON XAVIER NX 开发者套件的SD镜像 xff08 官网下载 xf
  • NVIDIA JETSON XAVIER NX 从SSD盘启动

    0 前言 本文主要补充上文提到的Jetson Xavier Nx系统从ssd盘启动 xff0c 需要准备的东西 xff1a 提前把ssd卡装上Jetson Xavier Nx套件上 xff0c 如下图 1 格式化为GPT 打开ubuntu的
  • 在linux虚拟机上安装docker

    1 简介 Docker是一个开源的应用容器引擎 xff1b 是一个轻量级容器技术 xff1b Docker支持将软件编译成一个镜像 xff1b 然后在镜像中各种软件做好配置 xff0c 将镜像发布出去 xff0c 其他使用者可以直接使用这个
  • win11虚拟机如何安装 Windows11虚拟机安装步骤教程

    想要体验下最新的win11系统 但是又不想在实体机上安装 担心出现系统故障问题怎么办 我们可以通过虚拟机安装win11系统实现 下面小编就教下大家虚拟机如何安装win11系统 更多Windows11系统教程可以参考小白一键网 1 下载安装好
  • Win11如何开启移动热点?Win11开启移动热点的方法

    在Win10系统之后就有了一个移动热点功能 xff0c 这在Win11系统也不例外 xff0c 不过很多小伙伴并不清楚Win11系统中的移动热点功能如何开启 xff0c 那么下面就和小编一起来看看Win11开启移动热点的方法 xff0c 有
  • 交换机组建局域网

    说来惭愧 xff0c 今天才搞明白用交换机组建局域网的原理 xff0c 这里介绍方法 xff1a 平时使用的路由器有交换机的功能 xff0c 单纯使用交换机还是第一次 xff1a 1 将所有电bai脑连到同一台交换机上 xff0c du即将
  • mavros 使用经验记录

    我用的飞控硬件板是pixhawk xff0c 用missionplanner刷的fight stack是apm的最新版本3 4 amp对mavros支持不是特别好 xff0c 如果合适还是用px4的flight stack 比较好 xff0
  • ros catkin_make 出现add_custom_target cannot create target 错误

    今天用catkin make编译ros包出现如下错误 CMake Error at home liwei work catkin ws land build mycommbase cmake mycommbase genmsg cmake
  • mavros使用经验记录二

    项目是一个无人机视觉追踪功能 xff0c 无人机上的协从计算机通过串口连接到飞控的tel2 接收mavlink消息流 xff0c 协计算机将此mavlink流进行udp转发到地面站 xff0c 同时协计算机实时的进行图像处理 xff0c 将
  • Unix Shell中单引号、双引号字符、反斜杠、反引号的使用

    在执行shell脚本的时候 xff0c shell将会对脚本中的行进行解释 xff0c 然后执行 xff1b 对于一些特殊处理的句子 xff0c 我们可以使用引号或者反斜线来避免shell解释执行之 如下 xff0c 当在命令行中输入 xf
  • TX2 Ubuntu 系统默认root用户登录 (永久权限)

    操作简单 xff0c 亲测可行 xff0c 不需要写啥脚本 https jingyan baidu com article 6181c3e0780131152ef153ff html
  • nginx部署多个vue项目的2种方法

    第一种 同一个域名或者ip 相同端口号 部署多个项目 通过斜线访问 http 10 16 xx 23 student http 10 16 xx 23 先看这2种配置 查找nginx 和配置文件 whereis nginx 查看配置文件 v
  • 用C++写一个简单的服务器(Linux)

    用C 43 43 写一个简单的服务器 Linux 下面是创建一个简单服务器的基本流程 xff0c 所用的端口是8099 后面贴了代码 一 基本流程 xff1a 创建套接字配置服务器地址相关参数将两者绑定监听套接字上的端口在上面创建的套接字上