套接字通信基础

news2025/6/15 15:48:30

套接字通信基础

  • 概述
  • 套接字通信基础
    • 套接字类型
    • socket模型创建流程分析
    • 套接字创建socket()
    • 套接字绑定bind()
    • 套接字监听listen()
    • 套接字接受连接请求accept
    • 套接字连接
    • 套接字数据传输
  • 套接字通信实例
    • 服务器端代码
    • 客户端代码
  • 应用场景
  • 总结

概述

套接字通信是在Linux系统中实现进程间通信(IPC)的一种方式,它可以在同一主机或不同主机上的进程之间传递数据。在本文中,我们将介绍套接字通信的基本概念、实现方法和常见应用场景,并提供相应的代码示例,以便初学者可以快速掌握该技术。

套接字通信基础

套接字类型

在Linux系统中,有两种类型的套接字:流式套接字(SOCK_STREAM)和数据报套接字(SOCK_DGRAM)。

流式套接字提供一个面向连接的、可靠的、基于字节流的双向数据传输通道。它通过TCP协议实现,支持数据传输的顺序和完整性保证。
数据报套接字提供无连接的、不可靠的、基于数据报的双向数据传输通道。它通过UDP协议实现,适用于数据量较小的通信场景。
地址族
套接字通信还需要使用地址族来指定网络地址和端口号。常用的地址族有IPv4(AF_INET)和IPv6(AF_INET6)。

socket模型创建流程分析

在这里插入图片描述

套接字创建socket()

套接字的创建可以通过socket()系统调用完成。其基本语法如下:

#include <sys/socket.h>

int socket(int domain, int type, int protocol);

参数说明:

domain:地址族,可以是AF_INET或AF_INET6,AF_UNIX。
type:套接字类型,可以是SOCK_STREAM或SOCK_DGRAM。
protocol:协议,可以是IPPROTO_TCP或IPPROTO_UDP。如果指定为0,系统会根据type自动选择默认协议。
成功创建套接字后,返回一个非负整数的文件描述符,
失败时返回-1。

套接字绑定bind()

套接字的绑定可以通过bind()系统调用完成。其基本语法如下:

`

#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数说明:

sockfd:套接字文件描述符。
addr:指向要绑定的本地地址的结构体指针,类型为sockaddr_in或sockaddr_in6。
addrlen:本地地址结构体的长度,通常是sizeof(sockaddr_in)或sizeof(sockaddr_in6)。

套接字监听listen()

如果需要在流式套接字上接受连接请求,需要先将套接字设置为监听状态。这可以通过listen()系统调用完成。listen可以设置同时与服务器建立连接的上限数。(同时进行3次握手的客户端数量)
其基本语法如下:

#include <sys/socket.h>

int listen(int sockfd, int backlog);

参数说明:

sockfd:套接字文件描述符。
backlog:指定等待连接的队列长度。

套接字接受连接请求accept

在流式套接字上监听到连接请求后,可以使用accept()系统调用接受连接请求,创建一个新的套接字用于和客户端进行通信。故一次通信至少有三个套接字,创建完后accept返回继续监听请求(深藏功与名)
其基本语法如下:

#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

参数说明:

sockfd:套接字文件描述符。
addr:指向存放客户端地址的结构体指针,类型为sockaddr_in或sockaddr_in6。是一个传出参数
addrlen:客户端地址结构体的长度,通常是sizeof(sockaddr_in)或sizeof(sockaddr_in6)。传入传出。 (入:addr的大小。 出:客户端addr实际大小。)
成功接受连接请求后,返回一个新的文件描述符,用于和客户端进行通信。失败时返回-1。

套接字连接

在流式套接字上向指定的目标主机发起连接请求,可以使用connect()系统调用。其基本语法如下:

#include <sys/socket.h>

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数说明:

sockfd:套接字文件描述符。
addr:指向要连接的远程主机地址的结构体指针,类型为sockaddr_in或sockaddr_in6。
addrlen:远程主机地址结构体的长度,通常是sizeof(sockaddr_in)或sizeof(sockaddr_in6)。
成功建立连接后,返回0,失败时返回-1。

套接字数据传输

套接字的数据传输可以使用send()和recv()系统调用完成。其基本语法如下:

#include <sys/socket.h>

ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);

参数说明:

sockfd:套接字文件描述符。
buf:指向数据缓冲区的指针。
len:数据长度。
flags:传输标志,可以是0或MSG_DONTWAIT等。
成功发送或接收数据后,返回实际传输的数据长度,失败时返回-1。

套接字通信实例

下面是一个简单的套接字通信实例,使用TCP协议进行数据传输。

服务器端代码

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

#define PORT 8888
#define BUFFER_SIZE 1024

int main() {
    int server_fd, client_fd;
    struct sockaddr_in server_addr, client_addr;
    char buffer[BUFFER_SIZE];
    int len;

    // 创建套接字
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // 绑定本地地址
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(PORT);
    if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("bind");
        exit(EXIT_FAILURE);
    }

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


// 等待连接请求
printf("Server is listening on port %d...\n", PORT);
socklen_t client_addr_len = sizeof(client_addr);
client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_len);
if (client_fd == -1) {
    perror("accept");
    exit(EXIT_FAILURE);
}

// 读取客户端发来的数据
memset(buffer, 0, sizeof(buffer));
len = recv(client_fd, buffer, sizeof(buffer), 0);
if (len == -1) {
    perror("recv");
    exit(EXIT_FAILURE);
}
printf("Received message from client: %s\n", buffer);

// 向客户端发送数据
strcpy(buffer, "Hello from server!");
len = send(client_fd, buffer, strlen(buffer), 0);
if (len == -1) {
    perror("send");
    exit(EXIT_FAILURE);
}
printf("Sent message to client: %s\n", buffer);

// 关闭套接字
close(client_fd);
close(server_fd);

return 0;
}

小知识:如果只写了服务端代码,可以用以下命令模拟客户端进行测试

nc 127.0.0.1 $(端口号)

客户端代码

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

#define SERVER_IP "127.0.0.1"
#define PORT 8888
#define BUFFER_SIZE 1024

int main() {
    int client_fd;
    struct sockaddr_in server_addr;
    char buffer[BUFFER_SIZE];
    int len;

    // 创建套接字
    client_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (client_fd == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // 连接服务器
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
    server_addr.sin_port = htons(PORT);
    if (connect(client_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("connect");
        exit(EXIT_FAILURE);
    }

    // 向服务器发送数据
    strcpy(buffer, "Hello from client!");
    len = send(client_fd, buffer, strlen(buffer), 0);
    if (len == -1) {
        perror("send");
        exit(EXIT_FAILURE);
    }
    printf("Sent message to server: %s\n", buffer);

    // 读取服务器返回的数据
    memset(buffer, 0, sizeof(buffer));
    len = recv(client_fd, buffer, sizeof(buffer), 0);
    if (len == -1) {
        perror("recv");
        exit(EXIT_FAILURE);
    }
    printf("Received message from server: %s\n", buffer);

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

    return 0;
}

在上述代码中,服务器端首先创建一个套接字,然后绑定到本地地址,并监听连接请求。当有客户端发起连接请求后,服务器端调用accept()系统调用接受连接请求,并创建一个新的套接字与客户端进行通信。

客户端首先创建一个套接字,然后连接到服务器端,向服务器端发送数据,接收服务器端的返回数据,并关闭套接字。

这个实例中了解了套接字通信的基本原理和实现,下面来介绍一些套接字通信的应用场景。

应用场景

网络编程
套接字通信是网络编程中最基础的通信方式之一,网络编程可以实现客户端与服务器之间的通信,也可以实现两个客户端之间的通信。

比如一个聊天室的应用程序,可以用套接字通信实现多个客户端之间的实时通信。

进程间通信
套接字通信也可以用于进程间通信,不同进程之间可以通过套接字来交换数据。

比如,两个进程之间可以通过套接字通信实现父进程和子进程之间的数据传输,或者两个独立的进程之间通过套接字通信实现数据交换。

跨平台通信
套接字通信可以跨越不同的操作系统和编程语言来实现通信,因为套接字通信是基于标准的网络协议实现的。

这意味着,在不同的操作系统和编程语言中,只要遵循相同的网络协议,就可以使用套接字通信进行通信。

总结

本文介绍了套接字通信的基本原理和实现方法,包括套接字通信的类型、套接字通信的流程、以及套接字通信的代码实现。

套接字通信是网络编程中最基础的通信方式之一,也可以用于进程间通信和跨平台通信等多种场景。通过套接字通信,不同的客户端和服务器之间可以进行实时通信和数据交换,为不同的应用场景提供了强大的支持。

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

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

相关文章

WinForms 网格控件 - iGrid.NET 10.1.22 Crack

WinForms 网格控件 - iGrid.NET WinForms 的 10Tec 网格介绍 iGrid.NET 是适用于 Windows Forms 平台的多功能WinForms 网格控件&#xff0c;它是 Microsoft .NET Framework 和 .NET Core 的一部分。软件开发人员使用 iGrid for WinForms 来构建高度可调整的表格界面。它速度…

【MATLAB图像处理实用案例详解(10)】——基于Kalman滤波的目标跟踪预测红色小球位置

目录一、Kalman滤波二、Kalman滤波源程序三、Kalman滤波预测红色小球位置程序实现一、Kalman滤波 Kalman 滤波算法是一个最优化自回归数据处理算法&#xff0c;对于很多问题的解決&#xff0c;它是最优、效率最高甚至是最有用的。Kalman 滤波的广泛应用己经超过30年&#xff0…

LeetCode-120. 三角形最小路径和

目录题目思路动态规划(由上到下)动态规划(由下到上)题目来源 120. 三角形最小路径和 题目思路 由上往下 动态规划(由上到下) 1.确定dp数组以及下标的含义 dp[i][j] 表示从点 (i,j)) 到底边的最小路径和。 2.确定递推公式 常规&#xff1a; triangle[i][j]一定会经过tri…

SQL语句性能分析

1. 数据库服务器的优化步骤 当我们遇到数据库调优问题的时候&#xff0c;该如何思考呢&#xff1f;这里把思考的流程整理成下面这张图。 整个流程划分成了 观察&#xff08;Show status&#xff09; 和 行动&#xff08;Action&#xff09; 两个部分。字母 S 的部分代表观察&…

连续可调稳压升压电源模块12v转12kv 24v转15kv 12v转5000v

GRB系列高压电源模块是一款工业级高性能微型DC/DC电源模块&#xff0c;是目前全球实 现输出连续可调稳压1000-15000V的超小体积的高压电源模块。具有体积小、功 耗低、响应快、输出纹波低、输出稳定度高、输出电压宽范围可调、自带过流保 护等优点&#xff0c;是一款专门为工业…

uniapp 之 小球根据当前时间 显示位置

目录 效果图 前言 总代码 1. template 代码 2. script 代码 3. js文件 4.样式 注解 1.小球运动代码 2. picker 时间选择器 补充 效果图 前言 最里面的是一张图片&#xff0c;并不是手写的样式&#xff0c; 总代码 1. template 代码 <uni-popup ref"appointm…

一图看懂 stat 模块:解析 stat() 结果, 资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 [TOC](一图看懂 stat 模块&#xff1a;解析 stat() 结果, 资料整理笔记&#xff08;大全&#xff09;) 摘要 全文介绍系统内置 stat 模块、函数、类及类的方法和属性。 它通过代码抓…

通过自动化和条形码优化供应链

Welch Allyn是全球领先的医疗诊断设备制造商&#xff0c;开发了数百种突破性产品和技术&#xff0c;使一线从业者能够提供卓越的患者护理。它在26个不同的国家拥有近2&#xff0c;500名员工。 一、面临的挑战提高运营效率 原因&#xff1a;用户需要长途跋涉并浏览多个数据条目以…

HCIA第一次笔记

目录 网络基础 扩大网络的两种途径 1.增加网络节点——集线器(HUB) 2.增大传输距离——中继器(放大器) 解决网络问题——网桥、交换机(二层设备) 交换机——读和重写的操作 解决洪泛——路由器(三层设备) 区分是否在同一个洪泛范围——IP(Internet Protocol)地址 ARP协…

redis缓存穿透、案例

1、缓存穿透是什么 缓存穿透是指查询一个一定不存在的数据&#xff0c;由于缓存是不命中时需要从数据库查询&#xff0c;查不到数据则不写入缓存&#xff0c;这将导致这个不存在的数据每次请求都要到数据库去查询&#xff0c;进而给数据库带来压力。 其实&#xff1a;就是黑客…

多线程冲突处理方法,锁

线程之间是可以共享进程的资源&#xff0c;比如代码段、堆空间、数据段、打开的文件等资源&#xff0c;但每个线程都有自己独立的栈空间。 那么问题就来了&#xff0c;多个线程如果竞争共享资源&#xff0c;如果不采取有效的措施&#xff0c;则会造成共享数据的混乱。 我们做…

STM32+收发器实现CAN和485总线

RS485总线是一种常见的(Recommended Standard)串行总线标准(485是它的标识号)&#xff0c;采用平衡发送与差分接收的方式&#xff0c;因此具有抑制共模干扰的能力。CAN是控制器局域网络(Controller Area Network, CAN)的简称&#xff0c;是一种能够实现分布式实时控制的串行通信…

推特爆火!揭晓大模型的未来何去何从

文 | 智商掉了一地巨大挑战 or 发展契机&#xff0c;ChatGPT 和 GPT-4 出现后&#xff0c;大模型的未来方向该何去何从&#xff1f;近期&#xff0c;自然语言处理领域的快速发展引起了广泛的关注&#xff0c;尤其是大型语言模型&#xff08;LLM&#xff09;的兴起已经推动了该领…

4.13、TCP通信流程

4.13、TCP通信流程1.TCP与UDP的区别&#xff08;传输层协议&#xff09;2.TCP通信流程①服务器端&#xff08;被动接受连接的角色&#xff09;②客户端&#xff08;主动发起连接&#xff09;1.TCP与UDP的区别&#xff08;传输层协议&#xff09; UDP:用户数据报协议&#xff0…

【Linux系统文件管理(cat,awk指令)和网络IP配置,广播地址,修改子网掩码以及ping网关地址】

文本操作实验 &#xff08;1&#xff09;使用cat&#xff0c;创建文件test1&#xff0c;输入"Line1"并且按下Ctrl-D保存文件。 创建text01.txt文件&#xff1a; cat > text01.txt 回车&#xff1b;输入自己想要输入的内容 键盘上面按下Ctrl-D就可以成功创建并保存…

【Java版oj】day24洗牌、MP3光标位置

目录 一、洗牌 &#xff08;1&#xff09;原题再现 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;完整代码 二、MP3光标位置 &#xff08;1&#xff09;原题再现 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;完整代码 一、洗牌 &#x…

西安石油大学C++上机实验 上机三:继承和派生程序设计(2学时)

上机三&#xff1a;继承和派生程序设计&#xff08;2学时&#xff09; 实验目的 了解继承在面向对象程序设计中的重要作用。 理解继承与派生的概念。 掌握通过继承派生出一个新类的方法。 掌握虚基类的作用和用法。 实验内容 P169&#xff1a;5.19, 5.22 上机内容 先设…

Windows 10 上使用 CMake GUI 编译 Krita 源代码并使用 MinGW 64 作为构建工具

krita系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文…

TCP和UDP(嵌入式学习)

TCP和UDPTCP&#xff08;即传输控制协议&#xff09;TCP连接建立(三次握手)TCP连接终止&#xff08;四次挥手&#xff09;UDP &#xff1a;用户数据报协议适用情况UDP 洪水UDP TCP 协议相同点TCP&#xff08;即传输控制协议&#xff09; 是一种面向连接的传输层协议&#xff0…

Vue ElementUI Axios 前后端案例(day01)

前言js 问js是什么&#xff0c;他有什么作用&#xff0c;与html和css的区别是什么 JavaScript&#xff08;简称JS&#xff09;是一种脚本语言&#xff0c;用于在网页上实现交互效果、动态效果和动态数据更新等功能。它是一种解释性语言&#xff0c;需要在浏览器中解释和执行。…