Socket进程间通信,从概念到实战(TCP,UDP,linux环境下C语言代码编写)

news2024/9/23 9:36:47

1、socket简述

Socket是一种通信机制,通过它可以在不同主机之间进行数据交换。在Socket编程中,有两种常见的通信模式:客户端-服务器模式和点对点模式。它基于TCP/IP协议栈,并使用IP地址和端口号来标识通信的目标。

2、Socket 基于TCP开发流程

服务端

1.创建套接字:int serverSocket = socket(AF_INET, SOCK_STREAM, 0);


2.绑定地址:struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); serverAddress.sin_addr.s_addr = INADDR_ANY; bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));


3.监听连接:listen(serverSocket, backlog);


4.接受连接:struct sockaddr_in clientAddress; int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, sizeof(clientAddress));


5.发送和接收数据:send(clientSocket, buffer, size, 0); recv(clientSocket, buffer, size, 0);


6.关闭连接:close(clientSocket); close(serverSocket);

客服端:

1.创建套接字:int clientSocket = socket(AF_INET, SOCK_STREAM, 0);


2.连接服务器:struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); serverAddress.sin_addr.s_addr = inet_addr(serverIP); connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));


3.发送和接收数据:send(clientSocket, buffer, size, 0); recv(clientSocket, buffer, size, 0);


4.关闭连接:close(clientSocket);

3、Socket 基于UDP开发流程

服务端

1.创建套接字:int serverSocket = socket(AF_INET, SOCK_STREAM, 0);


2.绑定地址:struct sockaddr_in serverAddress; serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); serverAddress.sin_addr.s_addr = INADDR_ANY; bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));


3.发送和接收数据:send(clientSocket, buffer, size, 0); recv(clientSocket, buffer, size, 0);


4.关闭连接:close(clientSocket); close(serverSocket);

客服端:

1.创建套接字:int clientSocket = socket(AF_INET, SOCK_STREAM, 0);


2.发送和接收数据:send(clientSocket, buffer, size, 0); recv(clientSocket, buffer, size, 0);


3.关闭连接:close(clientSocket);

4、代码实战

1.TCP

server.c

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

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int serverSocket, clientSocket;
    struct sockaddr_in serverAddr, clientAddr;
    socklen_t clientAddrLen;
    char buffer[BUFFER_SIZE];

    // 创建服务端套接字
    serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == -1) {
        perror("Failed to create socket");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址信息
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    // 绑定套接字到指定地址和端口
    if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Failed to bind socket");
        exit(EXIT_FAILURE);
    }

    // 监听连接请求
    if (listen(serverSocket, 5) == -1) {
        perror("Failed to listen");
        exit(EXIT_FAILURE);
    }

    printf("Server listening on port %d...\n", SERVER_PORT);

    // 接受客户端连接
    clientAddrLen = sizeof(clientAddr);
    clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &clientAddrLen);
    if (clientSocket == -1) {
        perror("Failed to accept client connection");
        exit(EXIT_FAILURE);
    }

    printf("Client connected: %s\n", inet_ntoa(clientAddr.sin_addr));

    // 接收数据
    memset(buffer, 0, sizeof(buffer));
    if (recv(clientSocket, buffer, BUFFER_SIZE, 0) == -1) {
        perror("Failed to receive data");
        exit(EXIT_FAILURE);
    }

    printf("Client message: %s\n", buffer);

    // 发送响应
    strcpy(buffer, "Hello, Client!");
    if (send(clientSocket, buffer, strlen(buffer), 0) == -1) {
        perror("Failed to send data");
        exit(EXIT_FAILURE);
    }

    // 关闭套接字
    close(clientSocket);
    close(serverSocket);

    return 0;
}

client.c

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


#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int clientSocket;
    struct sockaddr_in serverAddr;
    char buffer[BUFFER_SIZE];

    // 创建客户端套接字
    clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket == -1) {
        perror("Failed to create socket");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址信息
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    if (inet_pton(AF_INET, SERVER_IP, &(serverAddr.sin_addr)) <=

 0) {
        perror("Failed to set server IP");
        exit(EXIT_FAILURE);
    }

    // 连接到服务器
    if (connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Failed to connect to server");
        exit(EXIT_FAILURE);
    }

    printf("Connected to server %s:%d\n", SERVER_IP, SERVER_PORT);

    // 发送数据
    strcpy(buffer, "Hello, Server!");
    if (send(clientSocket, buffer, strlen(buffer), 0) == -1) {
        perror("Failed to send data");
        exit(EXIT_FAILURE);
    }

    // 接收响应
    memset(buffer, 0, sizeof(buffer));
    if (recv(clientSocket, buffer, BUFFER_SIZE, 0) == -1) {
        perror("Failed to receive data");
        exit(EXIT_FAILURE);
    }

    printf("Server response: %s\n", buffer);

    // 关闭套接字
    close(clientSocket);

    return 0;
}

2.UDP

server.c

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

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int serverSocket;
    struct sockaddr_in serverAddr, clientAddr;
    socklen_t clientAddrLen;
    char buffer[BUFFER_SIZE];

    // 创建服务端套接字
    serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
    if (serverSocket == -1) {
        perror("Failed to create socket");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址信息
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    // 绑定套接字到指定地址和端口
    if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Failed to bind socket");
        exit(EXIT_FAILURE);
    }

    printf("Server listening on port %d...\n", SERVER_PORT);

    // 接收数据
    clientAddrLen = sizeof(clientAddr);
    memset(buffer, 0, sizeof(buffer));
    if (recvfrom(serverSocket, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&clientAddr, &clientAddrLen) == -1) {
        perror("Failed to receive data");
        exit(EXIT_FAILURE);
    }

    printf("Client message: %s\n", buffer);

    // 发送响应
    strcpy(buffer, "Hello, Client!");
    if (sendto(serverSocket, buffer, strlen(buffer), 0, (struct sockaddr *)&clientAddr, clientAddrLen) == -1) {
        perror("Failed to send data");
        exit(EXIT_FAILURE);
    }

    // 关闭套接字
    close(serverSocket);

    return 0;
}

client.c

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


#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int clientSocket;
    struct sockaddr_in serverAddr;
    char buffer[BUFFER_SIZE];

    // 创建客户端套接字


    clientSocket = socket(AF_INET, SOCK_DGRAM, 0);
    if (clientSocket == -1) {
        perror("Failed to create socket");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址信息
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    if (inet_pton(AF_INET, SERVER_IP, &(serverAddr.sin_addr)) <= 0) {
        perror("Failed to set server IP");
        exit(EXIT_FAILURE);
    }

    printf("Connected to server %s:%d\n", SERVER_IP, SERVER_PORT);

    // 发送数据
    strcpy(buffer, "Hello, Server!");
    if (sendto(clientSocket, buffer, strlen(buffer), 0, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Failed to send data");
        exit(EXIT_FAILURE);
    }

    // 接收响应
    memset(buffer, 0, sizeof(buffer));
    if (recvfrom(clientSocket, buffer, BUFFER_SIZE, 0, NULL, NULL) == -1) {
        perror("Failed to receive data");
        exit(EXIT_FAILURE);
    }

    printf("Server response: %s\n", buffer);

    // 关闭套接字
    close(clientSocket);

    return 0;
}

3.Linux系统TCP通信实操

创建两个.c文件 socket_server.c 和 socket_client.c(名字可以自己取)

不会vi编译器的直接使用最简单的gedit操作,把代码复制进去 save.

现在创建好两个文件,可以进行gcc编译,生成两个可执行文件。

打开两个cmd 窗口,首先运行socket_server,再运行socket_client就可以通信成功。

 

最后说一下TCP 和UDP 代码是不同的,TCP是面向可靠的连接传输,UDP是面向不可靠的,所以TCP连接要复杂一点。

如有侵权,请联系删除。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2034131.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构--树与二叉树

数据结构分类 集合 线性结构(一对一) 树形结构(一对多) 图结构(多对多) 数据结构三要素 1、逻辑结构 2、数据的运算 3、存储结构&#xff08;物理结构&#xff09; 树的概念 树的分类 满二叉树和完全二叉树 二叉排序树 平衡二叉树 二叉树分类总结 二叉树的存储结构 …

NVIDIA液冷技术革新:GB200 的挑战与机遇

英伟达 (Nvidia) 最近的一个创新与比特和字节无关。这是一项液冷技术创新。英伟达即将推出的 GB200 服务器机架将主要通过在硬件管道里循环的液体、而不是空气来冷却&#xff0c;该机架包含英伟达下一代 Blackwell 芯片。 英伟达发言人表示&#xff0c;该公司还在与供应商合作…

【人工智能】助力音乐产业

了解人工智能如何通过先进的制作和作曲工具改变音乐产业&#xff0c;创造创新的声音并重塑音乐创作。 人工智能在音乐行业中发挥着重要作用&#xff08;这是双关语&#xff09;。它影响着从艺术家创作音乐的方式到营销和发行的一切。鉴于人工智能的巨大力量&#xff0c;这项创新…

探索数据可视化,数据看板在各行业中的应用

数据可视化是一种通过图形化手段将数据呈现出来的技术&#xff0c;它将复杂的数据和信息转化为易于理解的图表、地图、仪表盘等视觉元素&#xff0c;使得数据的模式、趋势和关系更加直观地展现出来。通过数据可视化&#xff0c;用户可以快速识别重要信息、发现潜在问题&#xf…

【网络】IO

IO 一、五种IO模型同步通信 vs 异步通信阻塞 vs 非阻塞 二、其他高级IO非阻塞IOSetNoBlockI/O多路转接之selectselect函数原型fd_set&#xff08;位图&#xff09;select代码select缺点poll&#xff08;用select修改&#xff09; I/O多路转接之epoll高级版改进select和poll的问…

Spring Boot 3.x Web MVC实战:实现流缓存的request

上一节《Spring Boot 3.x Filter实战&#xff1a;记录请求日志》实践最后遇到了request对象的流不可重复读的问题&#xff0c;本小节我们将通过流数据缓存以及流的装饰器模式来解决这个问题。如果觉得对你有帮助&#xff0c;记得点赞收藏&#xff0c;关注小卷&#xff0c;后续更…

搭建高可用OpenStack(Queen版)集群(十)之部署分布式存储Ceph

一、Ceph知识点学习 Ceph知识点学习&#xff1a;https://www.cnblogs.com/happy-king/p/9207509.html 二、部署分布式存储Ceph 一&#xff09;设置yum源 在全部控制与计算节点设置epel与ceph yum源 epel源&#xff1a;repo安装包下载_开源镜像站-阿里云 ceph源&#xff1a;cep…

Idea2023.3.3 —— SourceTree与gitee关联

SourceTree SourceTree链接: https://pan.baidu.com/s/1oqPxhpHeNOOiuRRQydes6g?pwdngru 提取码: ngru 点击Generate 分别保存私钥和公钥 gitee官网注册 这是gitee的公钥&#xff0c;与上面SourceTree的公钥私钥不一样 gitee生成公钥&#xff0c;确保本地安装好git git链接: h…

高级组件封装技巧--按钮的封装

我们做一些重要操作的时候&#xff0c;往往需要弹窗一个提示框&#xff0c;告诉用户这是一个需要小心的操作&#xff0c;是否继续&#xff0c;用户点击确定后才会开始执行&#xff0c;这种操作写起来比较繁琐&#xff0c;如下所示&#xff0c;要写一堆代码&#xff0c;今天我来…

2024年恩施建筑企业人员初中级专业技术职务评审

2024年恩施建筑企业人员初中级专业技术职务评审 恩施中级职称申报一般是一年1次&#xff0c;具体视情况而定。申报中级职称人员须相应专业水平能力测试成绩合格且在有效期内&#xff0c;同时应当符合相应专业申报条件。专业能力水平能力测试成绩3年有效。 2024年恩施建筑类初…

2024年8月 | 涉及侵权、抄袭洗稿违规行为公示

为护社区良好氛围&#xff0c;守护清朗网络空间&#xff0c;CSDN持续对侵害他人权益、抄袭洗稿违规内容进行治理。 今年7月&#xff0c;CSDN共计删除涉及抄袭洗稿内容xx篇&#xff0c;下架侵权资源xx个&#xff0c;封禁违规账号42个。 部分违规账号公示 账号昵称处置结果封禁创…

STM32CubeMX学习记录——串口通信(含蓝牙通信)

文章目录 一、学习目的二、CubeMX配置三、代码编写 一、学习目的 串口通信是一种简单且广泛应用的通信方式。本文的学习目标是通过CubeMX工具配置串口通信&#xff0c;并编写相应代码&#xff0c;以实现串口助手打印信息以及蓝牙通信等功能。 二、CubeMX配置 &#xff08;1&am…

docker容器常用指令,dockerfile

docker&#xff1a;容器&#xff0c;主要是解决环境迁移的问题&#xff0c;将环境放入docker中&#xff0c;打包成镜像。 docker的基本组成&#xff1a;镜像(image)&#xff0c;容器(container)&#xff0c;仓库(repository)。镜像相当于类&#xff0c;容器相当于类的实例对象…

0基础深度学习项目12:基于TensorFlow实现彩色图片分类

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 目录 一、创建环境二、前期准备2.1 设置GPU2.2 导入数据2.2.1 在TensorFlow框架中导入CIFAR-10数据集2.2.2 数据归一化 2.3数据可视化 三、构建简单的CNN网络&…

kubernetes集群部署oracle 11g数据库服务

背景&#xff1a; 因业务上线需要&#xff0c;研发中心要求在kubernetes测试集群部署一个oracle 11g的数据库&#xff0c;用于业务功能调试。 一、实施部署oracle 11g数据库&#xff1a; 1、拉取oracle 11g的镜像&#xff1a; [rootharbor-02 ~]# docker pull registry.cn-h…

Java之MySQL

1、数据库三大范式 每个字段不可再分&#xff0c;不冗余 非主键字段完全依赖于主键 2、drop 删除整张表&#xff0c;不可回滚&#xff1b;delete删除部分数据行&#xff1b;truncate保留表 删除所有数据 3、innodb存储引擎 支持行级锁、表级锁 支持事务 支持异常奔溃后的安…

拓普壹的选品师项目怎么操作更好?

在拓普壹的选品师项目中&#xff0c;成功的关键在于精细化的操作和系统化的策略。这不仅要求选品师具备深厚的自身能力&#xff0c;还需要明智的选择平台和有效利用新技术。本文将从这三个方面探讨如何更好地操作拓普壹选品师项目。 1. 自身能力培养 选品师的核心任务是从众多商…

SPRING07_自动装配如何加强、@Autowired注解debug分析、总结

文章目录 ①. Spring启动一行代码:②. ApplicationContex增强功能③. 自动装配如何装配进来④. Autowired自动注入细节xml版⑤. Autowired注解版分析⑥. 总结一下 ①. Spring启动一行代码: ①. 创建一个IOC容器,传入容器的xml配置文件,Spring在整个创建容器的过程中全部都准备…

Docker安装达梦数据库详细教程

达梦数据库(DM,Dameng Database)是中国自主研发的关系型数据库管理系统。它由武汉达梦数据库有限公司开发,最早可以追溯到1982年,至今已有几十年的发展历史。达梦数据库在中国市场上具有较高的知名度和市场占有率,特别是在政府、金融、电信、能源等行业有广泛的应用。 自…

深度学习——神经网络(neural network)详解(一). 带手算步骤,步骤清晰0基础可看

深度学习——神经网络&#xff08;neural network&#xff09;详解&#xff08;一&#xff09;. 带手算步骤&#xff0c;步骤清晰0基础可看 我将以最简单&#xff0c;基础的形式说明神经网络的训练过程。 搭配以下文章进行学习&#xff1a; 深度学习——卷积神经网络&#xf…