当前位置: 首页 > news >正文

【linux网络编程】套接字socket

Linux 套接字(Socket)详细介绍

1. 什么是套接字(Socket)?

套接字(Socket) 是计算机网络通信的编程接口(API),它允许不同计算机或同一计算机上的进程通过 TCP/IP 网络进行数据交换。

  • 本质:一个用于 进程间通信(IPC) 的端点,是应用程序访问网络的接口,用于在不同计算机或同一计算机的进程之间通信。

  • 作用:在应用程序和网络协议之间建立连接,允许数据收发。

  • 特点

    • 支持本机和远程通信(同一主机进程通信或不同主机进程通信)。
    • 屏蔽底层网络传输细节(应用程序不需要直接操作 TCP/IP 数据包)。
    • 支持 TCP/UDP 通信(可靠的 TCP 或无连接的 UDP)。
    • 支持多种协议族(IPv4、IPv6、本地通信)。

📌 套接字的地位

  • 不属于传输层,而是应用程序访问传输层(TCP/UDP)的接口
  • 允许应用程序调用 TCP/UDP 来实现可靠或无连接的数据传输

2. 套接字的基本工作原理

网络通信流程

  1. 客户端创建套接字,请求连接服务器。
  2. 服务器创建套接字,等待客户端连接。
  3. 服务器接受连接,建立数据通道。
  4. 双方进行数据收发
  5. 连接关闭

一个完整的 TCP 连接:

客户端(192.168.1.10:50000)   →  服务器(192.168.1.100:80)
请求数据                       ←  响应数据

UDP 连接(无连接):

客户端(192.168.1.10:50000)  →  服务器(192.168.1.100:53)
DNS 查询                      ←  DNS 响应

3. 套接字的基本类型

1️⃣ 按通信方式分类

套接字类型说明典型协议
流式套接字(SOCK_STREAM)面向连接,可靠,有流量控制TCP
数据报套接字(SOCK_DGRAM)无连接,不可靠,速度快UDP
原始套接字(SOCK_RAW)直接访问 IP 层,常用于网络分析ICMP、ARP

2️⃣ 按协议族分类

地址族说明适用范围
AF_INETIPv4 套接字互联网通信
AF_INET6IPv6 套接字互联网通信
AF_UNIX本地进程间通信(IPC)本机进程通信
AF_PACKET直接访问底层数据链路层抓包、ARP

4. 套接字编程 API

📌 套接字 API 主要函数(C 语言)

函数作用
socket()创建套接字
bind()绑定 IP 和端口
listen()监听连接(TCP 服务器端)
accept()接受客户端连接
connect()连接服务器(TCP 客户端)
send()/recv()TCP 发送/接收数据
sendto()/recvfrom()UDP 发送/接收数据
close()关闭套接字

5. TCP 套接字通信示例

📌 服务器端(TCP)

#include <winsock2.h>
#include <iostream>

#pragma comment(lib, "ws2_32.lib")  // 链接 Winsock 库

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    // 1. 初始化 Winsock
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "WSAStartup 失败" << std::endl;
        return 1;
    }

    // 2. 创建 Socket
    SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == INVALID_SOCKET) {
        std::cerr << "Socket 创建失败" << std::endl;
        WSACleanup();
        return 1;
    }

    // 3. 绑定地址
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(PORT);

    if (bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "绑定失败" << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }

    // 4. 监听连接
    if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR) {
        std::cerr << "监听失败" << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }
    std::cout << "服务器正在监听端口 " << PORT << "..." << std::endl;

    // 5. 接受客户端连接
    sockaddr_in clientAddr;
    int clientAddrSize = sizeof(clientAddr);
    SOCKET clientSocket = accept(serverSocket, (sockaddr*)&clientAddr, &clientAddrSize);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "接受连接失败" << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }
    std::cout << "客户端连接成功!" << std::endl;

    // 6. 接收数据
    char buffer[BUFFER_SIZE] = { 0 };
    int bytesReceived = recv(clientSocket, buffer, BUFFER_SIZE, 0);
    if (bytesReceived > 0) {
        std::cout << "收到客户端消息: " << buffer << std::endl;
    }

    // 7. 发送响应
    const char* response = "Hello from server!";
    send(clientSocket, response, strlen(response), 0);

    // 8. 关闭 Socket
    closesocket(clientSocket);
    closesocket(serverSocket);
    WSACleanup();

    return 0;
}


📌 客户端(TCP)

#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>

#pragma comment(lib, "ws2_32.lib")  // 链接 Winsock 库

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

int main() {
    // 1. 初始化 Winsock
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "WSAStartup 失败" << std::endl;
        return 1;
    }

    // 2. 创建 Socket
    SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "Socket 创建失败" << std::endl;
        WSACleanup();
        return 1;
    }

    // 3. 连接服务器
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(PORT);
    //serverAddr.sin_addr.s_addr = inet_addr(SERVER_IP);
    if (inet_pton(AF_INET, SERVER_IP, &serverAddr.sin_addr) <= 0) {
        std::cerr << "地址转换失败\n";
        closesocket(clientSocket);
        WSACleanup();
        return 1;
    }

    if (connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "连接服务器失败" << std::endl;
        closesocket(clientSocket);
        WSACleanup();
        return 1;
    }
    std::cout << "成功连接到服务器!" << std::endl;

    // 4. 发送数据
    const char* message = "Hello from client!";
    send(clientSocket, message, strlen(message), 0);

    // 5. 接收服务器响应
    char buffer[BUFFER_SIZE] = { 0 };
    int bytesReceived = recv(clientSocket, buffer, BUFFER_SIZE, 0);
    if (bytesReceived > 0) {
        std::cout << "收到服务器消息: " << buffer << std::endl;
    }

    // 6. 关闭 Socket
    closesocket(clientSocket);
    WSACleanup();

    return 0;
}


6. UDP 套接字通信

UDP 没有连接过程,数据直接发送:

  • sendto() 发送数据
  • recvfrom() 接收数据

7. 套接字通信流程

📌 TCP(面向连接)

  1. 服务器

    • socket() 创建套接字
    • bind() 绑定端口
    • listen() 监听端口
    • accept() 等待连接
    • recv()/send() 进行通信
    • close() 关闭连接
  2. 客户端

    • socket() 创建套接字
    • connect() 连接服务器
    • send()/recv() 进行通信
    • close() 关闭连接

📌 UDP(无连接)

  1. 服务器

    • socket() 创建套接字
    • bind() 绑定端口
    • recvfrom()/sendto() 接收/发送数据
    • close() 关闭
  2. 客户端

    • socket() 创建套接字
    • sendto() 发送数据
    • recvfrom() 接收数据
    • close() 关闭

8. 总结

  1. 套接字是应用程序访问网络的 API,不属于传输层
  2. TCP 使用 SOCK_STREAM,UDP 使用 SOCK_DGRAM
  3. 客户端通常使用动态端口,服务器使用固定端口
  4. socket() 是网络编程的入口,应用程序通过它访问 TCP/UDP

📌 如果你想用 C 语言或 Python 进行网络编程,理解 socket 是最关键的一步! 🚀

相关文章:

  • 近三年图像超分辨率研究进展综述(轻量化方向)
  • 介绍高性能的HTTP和反向代理服务器Nginx
  • hbase-05 namespace、数据的确界TTL
  • python加载动态网站内容Playwright使用介绍
  • 小程序 wxml 语法 —— 39 简单双向数据绑定
  • 力扣1463. 摘樱桃 II
  • 存量思维和增量思维
  • Python代码调试方法集锦
  • 用DEEPSEEK做数据看板:高效、实用与创新的融合
  • android paging使用教程
  • open-webui+deepseek api实现deepseek自由
  • AI×电商数据API接口:深度融合,引领未来电商行业浪潮
  • Vulnhub-Node
  • leetcode69.x 的平方根
  • 《Python实战进阶》No16: Plotly 交互式图表制作指南
  • Python3 爬虫 爬虫中间件
  • AI系统架构
  • JS如何实现全选以及联动效果
  • Linux常见指令
  • leetcode-sql数据库面试题冲刺(高频SQL五十题)
  • 做设计找素材都有什么网站/百度竞价排名是什么方式
  • vs2013 网站建设/网站推广计划
  • 网络营销产品的特点/seo岗位职责
  • 那些论坛网站做的比较好/seo专员工作内容
  • 网站地图怎么添加/校园推广方案
  • 建设网站运营方案/公司网站制作要多少钱