linux学习之套接字通信

简介: Linux中的套接字通信是网络编程的核心,允许多个进程通过网络交换数据。套接字提供跨网络通信能力,涵盖本地进程间通信及远程通信。主要基于TCP和UDP两种模型:TCP面向连接且可靠,适用于文件传输等高可靠性需求;UDP无连接且速度快,适合实时音视频通信等低延迟场景。通过创建、绑定、监听及读写操作,可以在Linux环境下轻松实现这两种通信模型。

Linux中的套接字通信是网络编程的核心概念之一,它允许不同进程之间通过网络进行数据交换。套接字(Socket)是一种抽象层,为应用程序提供了跨越网络通信的能力,无论是同一台机器上的进程间通信(IPC),还是不同机器之间的远程通信。套接字通信主要基于两种模型:用户数据报协议(UDP)和传输控制协议(TCP)。下面将详细介绍这两种模型及如何在Linux环境下实现套接字通信。

TCP套接字通信

TCP(Transmission Control Protocol)是一种面向连接、可靠的、基于字节流的通信协议。在TCP通信中,数据在发送前需先建立连接,确保数据按序无误地到达对方。

步骤概述:

  1. 服务器端:

    • 创建套接字(socket):使用 socket()函数创建一个套接字,指定地址族(AF_INET)、套接字类型(SOCK_STREAM)和协议(默认为IPPROTO_TCP)。
    • 绑定地址(bind):通过 bind()函数将套接字与特定的IP地址和端口号绑定。
    • 监听连接(listen):调用 listen()函数使套接字进入监听状态,准备接受客户端的连接请求。
    • 接受连接(accept):使用 accept()函数等待并接受客户端的连接请求,返回一个新的套接字用于与该客户端通信。
    • 读写数据(read/write):通过新套接字进行数据的读取和写入。
    • 关闭连接(close):完成通信后,关闭套接字。
  2. 客户端:

    • 创建套接字:与服务器端相同,创建一个TCP套接字。
    • 连接服务器(connect):使用 connect()函数尝试与服务器的指定地址和端口建立连接。
    • 读写数据:一旦连接成功,即可通过套接字进行数据的读写操作。
    • 关闭连接:通信结束后,关闭套接字。

UDP套接字通信

UDP(User Datagram Protocol)是一种无连接的、不可靠的数据报协议。相比TCP,UDP不保证数据包的顺序或是否到达,但提供了较低的延迟和简单的通信机制,适用于对实时性要求较高而对数据完整性和顺序要求不高的场景。

步骤概述:

对于UDP,服务器端和客户端的流程与TCP类似,但省去了连接建立和监听步骤:

  • 服务器端:

    • 创建套接字,指定为UDP类型(SOCK_DGRAM)。
    • 绑定地址。
    • 使用 recvfrom()接收数据,并可选地使用 sendto()向特定地址发送数据,无需事先建立连接。
    • 关闭套接字。
  • 客户端:

    • 创建UDP套接字。
    • 直接使用 sendto()发送数据到服务器地址。
    • 可以使用 recvfrom()接收来自服务器的响应(如果需要)。
    • 关闭套接字。

示例代码片段

TCP服务器示例:

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main() {
    int listenfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(12345);

    bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
    listen(listenfd, 10);

    struct sockaddr_in cliaddr;
    socklen_t clilen = sizeof(cliaddr);
    int connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &clilen);

    char buffer[1024];
    read(connfd, buffer, 1024);
    printf("Received message: %s\n", buffer);
    write(connfd, "Hello from server", strlen("Hello from server"));

    close(connfd);
    close(listenfd);

    return 0;
}
​

TCP客户端示例:

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main() {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(12345);
    inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);

    connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));

    write(sockfd, "Hello from client", strlen("Hello from client"));
    char buffer[1024] = {0};
    read(sockfd, buffer, 1024);
    printf("Received message: %s\n", buffer);

    close(sockfd);

    return 0;
}
​

分析说明表

模型 特点 适用场景
TCP 面向连接、可靠、有序、重传机制、流量控制 文件传输、网页浏览、电子邮件等需要高可靠性传输的应用
UDP 无连接、快速、不保证顺序和可靠性 实时音视频通信、在线游戏、广播式服务等对低延迟有高要求的应用

通过上述介绍和示例,可以看出,在Linux下实现套接字通信是网络编程的基础,掌握TCP和UDP两种模式对于构建高效、稳定的网络应用至关重要。实际开发中,根据应用场景的具体需求选择合适的通信模型是关键。

目录
相关文章
|
2月前
|
NoSQL 关系型数据库 MySQL
Linux学习记录---(1、基本命令)
该博客文章提供了Linux系统中基本命令的使用记录,包括文件和目录操作、Redis服务管理、MySQL数据库操作以及Tomcat服务器的启动和检查。
Linux学习记录---(1、基本命令)
|
3月前
|
Ubuntu Linux vr&ar
IM跨平台技术学习(十二):万字长文详解QQ Linux端实时音视频背后的跨平台实践
本文详细记录了新版QQ音视频通话在 Linux 平台适配开发过程中的技术方案与实现细节,希望能帮助大家理解在 Linux 平台从 0 到 1 实现音视频通话能力的过程。
139 2
|
2月前
|
NoSQL Ubuntu Linux
Linux内核学习
Linux内核学习
57 3
|
2月前
|
Linux
Linux源码阅读笔记13-进程通信组件中
Linux源码阅读笔记13-进程通信组件中
|
2月前
|
消息中间件 安全 Java
Linux源码阅读笔记13-进程通信组件上
Linux源码阅读笔记13-进程通信组件上
|
1月前
|
Linux
使用qemu来学习Linux的休眠和唤醒
使用qemu来学习Linux的休眠和唤醒
|
1月前
|
Linux
linux内核原子操作学习
linux内核原子操作学习
|
1月前
|
Ubuntu Linux
用crash工具学习Linux内核 —— 查看cgroup_roots
用crash工具学习Linux内核 —— 查看cgroup_roots
|
1月前
|
Ubuntu Linux 调度
Linux内核学习
Linux内核学习
|
2月前
|
存储 人工智能 Ubuntu
Linux指令学习(一)
Linux指令学习(一)
66 0