Linux下利用TCP的服务端和客户端实现简单收发消息

2023-11-16

服务端采用了线程,可以同时提供给多台客户端连接

TCP的服务端------tcp_server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>


struct client_info
{
    char ip[16];
    unsigned short port;
    int sock;
};


void* comm_thr(void* arg);


int main()
{
    //第一步:创建套接字
    int sock_listen = socket(AF_INET, SOCK_STREAM, 0);

    if(sock_listen == -1)
    {
        perror("socket");
        return 1;
    }

    
    //设置套接字属性,以允许地址复用
    int val = 1;
    setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));

     //第二步:绑定地址
    struct sockaddr_in myaddr;
    myaddr.sin_family = AF_INET;//指定地址家族
    myaddr.sin_addr.s_addr = INADDR_ANY;//指定使用本机任意地址
    //myaddr.sin_addr.s_addr = inet_addr("114.115.246.184");//指定IP地址
    myaddr.sin_port = htons(3389);//指定端口号

    if(-1 == bind(sock_listen, (struct sockaddr*)&myaddr, sizeof(myaddr)))
    {
        perror("bind");
        return 1;
    }

    //第三步:监听
    if(-1 == listen(sock_listen, 5))//第二个参数表示连接等待队列的长度
    {
        perror("listen");
        return 1;
    }

    pthread_t tid;
    struct client_info* ci = NULL;

    while(1)
    {
        //第四步:接收客户端连接请求
        struct sockaddr_in client_addr;
        socklen_t addr_len = sizeof(client_addr);
        int sock_conn = accept(sock_listen, (struct sockaddr*)&client_addr, &addr_len);

        if(sock_conn == -1)
        {
            perror("accept");
            return 1;
        }
             /*
           accept 函数参数解读:
           第一个参数为监听套接字描述符;
           第二个参数为地址结构体(struct sockaddr_in)指针,用于接收客户端的地址信息,如果对客户端地址不感兴趣,就传 NULL;
           第三个参数为地址结构体长度,用于接收客户端地址长度,如果对客户端地址不感兴趣,就传 NULL。

           如果成功,accept 函数的返回值为这条连接对应的套接字(通常称为连接套接字),后面使用这个套接字进行收发数据。如果失败,其返回值为
 -1。

           调用 accept 函数时,如果没有任何客户端连接请求到来,该函数会阻塞调用线程直到成功接收到一个客户端连接请求或出现错误才返回。
           */

        ci = malloc(sizeof(struct client_info));

        if(ci == NULL)
        {
            perror("malloc");
            exit(1);
        }

        strcpy(ci->ip, inet_ntoa(client_addr.sin_addr));
        ci->port = ntohs(client_addr.sin_port);
        ci->sock = sock_conn;

        printf("\n客户端(%s:%d)已连接!\n", ci->ip, ci->port);

        if(pthread_create(&tid, NULL, comm_thr, ci))
        {
            perror("pthread_create");
            printf("\n客户端(%s:%d)已断开连接!\n", ci->ip, ci->port);
            close(sock_conn);
            free(ci);
            continue;
        }

    }
    //第七步:关闭监听套接字
    close(sock_listen);

    return 0;
}

void* comm_thr(void* arg)
{
    struct client_info* ci = (struct client_info*)arg;

    //线程资源释放
    pthread_detach(pthread_self());

    //第五步:收发数据
    char data[1000] = "I am ok!";

    int ret = send(ci->sock, data, sizeof(data), 0);

    if(ret == -1)
    {
        perror("send");
    }

    ret = recv(ci->sock, data, sizeof(data) - 1, 0);

    if(ret > 0)
    {
        data[ret] = '\0';
        printf("\n客户端(%s:%d)说:%s\n", ci->ip, ci-> port, data);
    }

    //第六步:断开连接
    close(ci->sock);

    printf("\n客户端(%s:%d)已断开连接!\n", ci->ip, ci->port);

    free(ci);

    pthread_exit(NULL);
}     

TCP的客户端 ------tcp_client.c

#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>



int main(int argc, char** argv)
{
    //第一步:创建套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);

    if(sock == -1)
    {
        perror("sock");
        return 1;
    }

    /*
    // 第 2 步:绑定地址(IP + Port)(显式绑定)
    // 这一步可以不做
    struct sockaddr_in myaddr;
    myaddr.sin_family = AF_INET;  // 指定地址家族
    myaddr.sin_addr.s_addr = INADDR_ANY;  // 指定使用本机任意地址(0.0.0.0)
    //myaddr.sin_addr.s_addr = inet_addr("124.71.188.13");  // 指定使用本机某个具体的 IP 地址
    myaddr.sin_port = htons(6666);  // 指定使用的端口号为 6666

    if(-1 == bind(sock, (struct sockaddr*)&myaddr, sizeof(myaddr)))
    {
        perror("bind");
        return 1;
    }
    */

    /*
    inet_addr 函数的作用:将字符串形式的 IP 地址转换为无符号 32 位整数形式(网络字节序)。
    htons 函数的作用:将某个短整数(short)从主机(host)字节序转换为网络(network)字节序。
    */

    //第三步:连接服务器
    struct sockaddr_in srv_addr;
    srv_addr.sin_family = AF_INET;
    srv_addr.sin_addr.s_addr = inet_addr(argv[1]);
    srv_addr.sin_port = htons(atoi(argv[2]));

    if(-1 == connect(sock, (struct sockaddr*)&srv_addr, sizeof(srv_addr)))
    {
        perror("connect");
        return 1;
    }

    //第四步:收发数据
    char data[100];

    int ret = recv(sock, data, sizeof(data), 0);   
    if(ret == -1)
    {
        perror("recv");
    }
    else
    {
        printf("服务器说:%s\n", data);
        printf("%ld\n", strlen(data));
    }

    while(1) sleep(1);

    //第五步:断开连接
    close(sock);
    return 0;
}       

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux下利用TCP的服务端和客户端实现简单收发消息 的相关文章

  • Linux 阻塞与非阻塞串行读取

    I have 这段代码 https stackoverflow com questions 6947413 how to open read and write from serial port in c用于在Linux中从串行读取 但我不
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • VSCODE 在 Linux 上不适用于我

    刚刚了解 VSCODE 很高兴尝试一下 我下载 解压并运行可执行文件 我得到 Code 2183 0429 201254 ERROR browser main loop cc 170 Running without the SUID san
  • 如何清理 Runtime.exec() 中使用的用户输入?

    我需要通过命令行调用自定义脚本 这些脚本需要很少的参数并在 Linux 机器上调用 当前版本容易出现各种shell注入 如何清理用户给出的参数 参数包括登录名和路径 Unix 或 Windows 路径 用户应该能够输入任何可能的路径 该路径
  • 如何防止 CMake 在构建时(而不是安装时)为共享库创建符号链接?

    我正在使用 CMake 在 Linux 上使用 Bullet3 构建一个项目 在构建整个解决方案时 它会构建附加了 SOVERSION 的 Bullet 输出库 并创建一个不带版本的符号链接 对于我的特定场景 我不喜欢这种行为 并且我不想编
  • 在哪里可以找到所有 C 标准库的源代码?

    我正在寻找所有 C 标准库的完整源代码 也就是说 我正在寻找 stdio h stdlib h string h math h 等的源代码 我想看看它们是如何创建的 我认为这取决于不同的平台 但 Linux 或 Windows 都会受到欢迎
  • 动态加载库和共享全局符号

    由于我在动态加载的库中观察到全局变量的一些奇怪行为 因此我编写了以下测试 首先我们需要一个静态链接库 头文件test hpp ifndef BASE HPP define BASE HPP include
  • 如何在 Linux 中显示进程状态(阻塞、非阻塞)

    有没有办法查询 Linux 进程表中进程的状态 以便能够演示执行查询时进程是正在运行还是被阻止 我的目标是从进程或程序的 外部 执行此操作 因为我希望从操作系统进程的角度来理解这一点 但欢迎任何想法 这是Python代码阻塞的过程 impo
  • C/C++ with GCC:静态地将资源文件添加到可执行文件/库

    有人知道如何使用 GCC 将任何资源文件静态编译为可执行文件或共享库文件吗 例如 我想添加永远不会改变的图像文件 如果它们改变了 我无论如何都必须替换该文件 并且不希望它们位于文件系统中 如果这是可能的 我认为这是因为 Visual C f
  • 无法使用 tar -cvpzf 解压完整目录

    把我的头敲在这上面 I used tar cvpzf file tar gz压缩一个完整的目录 我将文件移动到另一台服务器 并尝试解压缩复制存档的目录 无法使其发挥作用 bash 3 2 tar xvpzf news tar gz tar
  • 在linux中使用setcap [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 要将 cap net raw 功能添加到 例如 bin ping 我们使用以下命令 setcap cap net raw ep bin ping ep
  • 如何从powershell获取主机名?

    我如何获得hostname https stackoverflow com q 42014215 262852 for dur来自 powershell PS home thufir powershell gt PS home thufir
  • 并发 I/O - 缓冲区损坏、块设备驱动程序

    我开发块分层设备驱动程序 所以 我拦截WRITE请求并加密数据 并解密数据end bio 例行程序 在处理和READ要求 所以在单流中一切正常 但是 如果尝试同时从两个或更多进程执行 I O 我会遇到缓冲区内容损坏的情况 我没有任何本地存储
  • gnutls_handshake() 失败:握手失败 GIT

    一切都工作正常 但突然我收到错误 致命 无法访问 https 电子邮件受保护 cdn cgi l email protection name repo name git gnutls handshake 失败 握手失败 我在我的计算机和 E
  • 我可以告诉 Linux 不要交换特定进程的内存吗?

    有没有办法告诉 Linux 它不应该将特定进程的内存交换到磁盘 它是一个 Java 应用程序 所以理想情况下我希望有一种方法可以从命令行执行此操作 我知道您可以将全局交换性设置为 0 但这明智吗 您可以通过以下方式执行此操作姆洛克尔 2 h
  • Git - 致命:无法获取当前工作目录?

    When I git clone从回购协议中 我得到 fatal Could not get current working directory No such file or directory 我该怎么办 我检查了服务器并发现 git文
  • 检查上次更改密码的时间[关闭]

    Closed 这个问题是与编程或软件开发无关 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的
  • “以下软件包将被更高优先级的频道取代”是什么意思?

    我正在尝试将 fuzzywuzzy 安装到 64 位 Linux 中的 Anaconda 发行版上 当我这样做时 它试图改变我的conda and conda env to conda forge渠道 如下 我通过以下方式在 anacond
  • Tomcat 中的 403 访问被拒绝

    我有以下内容tomcat users xml
  • 如何告诉 CMake 将构建文件放在哪里?

    我想告诉 CMake 将文件和文件夹输出到不同的文件夹而不是当前文件夹 我在下面讨论的是 CMake 生成的文件 文件 CMakeCache txt 目录 CMakeFiles 文件 生成文件 目录 bin 文件 cmake install

随机推荐

  • 三十、纯虚函数、抽象类、多态、简单工厂模式

    一 纯虚函数 虚函数是多态是实现多态的前提 如果我们需要在基类中定义共同的结构 那么接口就需要定义成虚函数 但是很多情况下基类的接口是无法实现的 比如形状类Shape 定义一个Draw方法 很明显这个方法没法实现 因为我们可以画出圆 正方形
  • 乾坤微服务子项目图片资源加载失败

    一 背景 子项目单独运行时正常 放在乾坤上 img 加载图片时失败 二 分析原因 假设乾坤项目域名为 http www aaa com 子项目域名为 http www bbb com 项目实际运行时 图片的 html 写法为 img src
  • python:正向最大匹配法分词(以藏文为例)

    前段时间研究了如何用分词工具进行分词 但是分词中涉及的一些算法 不太了解 所以 准备这段时间专攻分词算法原理 大家有补充 或者建议 欢迎留言 1 最大匹配法 Maximum Matching 最大匹配法是指以词典为依据 取词典中最长词长度作
  • 某游戏大厂测开笔试题分享

    测开笔试题 某厂笔试题 执行时限1000ms 一个典型的电话拨号盘如下 1 2 3 4 5 6 7 8 9 0 手指在两个按键之间的移动距离被定义为这两个键的x y坐标差的绝对值之和 比如 6到自身的距离是0 到3 5 9键的距离是1 到2
  • 证件照如何换底色,分享三种证件照换底色的方法!

    在我们的日常生活中 不同场景需要使用不同颜色的证件照 如果我们需要更换证件照的背景颜色 通常情况下人们会选择去照相馆重新拍摄一组照片 但这样费时费力 而且在遇到紧急情况时可能来不及 本文将介绍三种非常实用的方法 希望能对您有所帮助 方法一
  • Langchain使用介绍之-文档加载

    Lanchain提供了加载多种文档的能力 Lanchain初了能加载txt csv等格式文档外 还支持加载网页 音频 pdf等 本篇博客将介绍如何通过Langchain完成PDF文档 音频文档 网页文档的加载 加载PDF文档 通过使用Lan
  • ChatGPT 中文调教指南。各种场景使用指南。学习怎么让它听你的话

    ChatGPT是由OpenAI训练的一款大型语言模型 能够生成类人文本 您只需要给出提示或提出问题 它就可以生成你想要的东西 在此页面中 您将找到可与 ChatGPT 一起使用的各种提示 正经指南 写小说 写一本拥有出人意料结局的推理小说
  • 1.1关于数据挖掘

    一 数据挖掘是什么 从技术层面讲 数据挖掘指从大量数据中提取潜在有用的信息和知识的过程 从商业层面讲 数据挖掘是一种对大量业务数据进行抽取 转换 分析和建模处理 并从中提取辅助商业决策的关键数据的商业信息处理技术 二 数据挖掘与传统传统数据
  • 2021-5-13 爬虫之Xpath的下载与安装,简单教学!

    5 13学习日记之Xpath Xpath的安装 怎么安装Xpath 问题一 Xpath的安装 XPath 是一门在 XML 文档中查找信息的语言 XPath 可用来在 XML 文档中对元素和属性进行遍历 简单来说 在进行网页信息爬取时 Xp
  • 抖音新版本抓包(绕过sslpinning证书校验)

    目录 前言 方案 frida 替换so Xposed 前言 当我们想要分析较新版本的接口时 会发现一个有趣的现象 无论是用Charles还是Fiddler 都会出现抓不到包的情况 如下图 这是因为使用SSL Pinning证书锁定技术 是一
  • mysql性能优化

    1 表字段要选择合适的属性 邮政编码设置char 6 就可以了 文本字段如省份或者性别用enum enum被当做数值型数据来处理 比文本类型快 2 建立索引 3 优化查询语句 查询条件里最好用in替代on 条件列表值如果连续 用betwee
  • 注意力机制——CAM、SAM、CBAM、SE

    CAM SAM CBAM详见 CBAM 即插即用的注意力模块 附代码 目录 1 什么是注意力机制 2 通道注意力机制 SE 1 Squeeze 2 Excitation 3 SE Block 3 CAM 4 SAM 5 CBAM 6 代码
  • 一篇文章入门C/C++自动构建利器之Makefile

    更多博文 请看音视频系统学习的浪漫马车之总目录 C C 编译 浅析C C 编译本质 一篇文章入门C C 自动构建利器之Makefile 升级构建工具 从Makefile到CMake Makefile简介 上一篇浅析C C 编译本质已经比较详
  • UE4修改splitScreen layout方式

    UE4自身提供了分屏显示的方法 可以分成两个屏幕 也可以分成三个屏幕 但提供的分屏布局方式有限 包括两个玩家分屏布局 Vertical Horizontal 三个玩家分屏布局 Favor Top Favor Bottom 这里提供给大家一种
  • 华为OD机试真题 Java 实现【光伏场地建设规划】【2023Q1 100分】

    一 题目描述 祖国西北部有一片大片荒地 其中零星的分布着一些湖泊 保护区 矿区 整体上常年光照良好 但是也有一些地区光照不太好 某电力公司希望在这里建设多个光伏电站 生产清洁能源 对每平方公里的土地进行了发电评估 其中不能建设的区域发电量为
  • 【TS】联合类型

    文章目录 TS 联合类型 1 普通变量声明 2 数组声明使用 3 函数中使用 TS 联合类型 联合类型即通过管道 将变量设置多种类型 赋值时可以根据设置的类型来赋值 1 普通变量声明 let res number string boolea
  • MySQL中的事务、索引、锁机制

    目录 一 MySQL基础架构 二 MySQL中的索引 1 什么是索引 索引的作用 2 索引的类型 1 主键索引 Primary Key 2 二级索引 辅助索引 3 索引的底层数据结构 1 B 树 B 树 2 为什么选择B B 树 为什么要用
  • 图块引用、属性块引用、创建新层表、ObjectArx开发中静态变量和全局变量要点

    一 图块设计技术 在AutoCAD数据库中 以各图块实际上市存储在块表记录里的实体集合 每个图块从一格AcDbBlockBegin对象开始 紧接着是一个或多个AcDbEntity对象 最后以AcDbBolckEnd对象结束 按其所属关系得层
  • Googleplay从服务器检索信息时出错。[DF-DFERH-01]

    googleapis cn services googleapis cn 两个地址强制走代理就OK了 转载于 https www cnblogs com Devopser p 10269312 html
  • Linux下利用TCP的服务端和客户端实现简单收发消息

    服务端采用了线程 可以同时提供给多台客户端连接 TCP的服务端 tcp server c include