C/C++ Linux Socket网络编程流程分析

C/C++ Linux Socket网络编程流程分析

什么是Socket

Socket是计算机网络中对于通信队列和编程接口的抽象。一句话概括,Socket是一种特殊的文件,它通过文件IO的方式向网络发送和接收数据。

Socket网络编程流程

  1. 创建Socket

创建一个Socket需要调用socket()函数,它有三个参数,分别是:地址族、类型、协议。在Linux中,地址族常用的有AF_INET(IPv4)和AF_INET6(IPv6)两种,类型常用的有SOCK_STREAM和SOCK_DGRAM两种,协议有TCP和UDP两种。

示例代码:

// 创建一个IPv4地址族、使用TCP协议的Socket
int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  1. 绑定Socket

在Socket创建之后,需要将这个Socket绑定到一个具体的端口上,在Linux中,端口号是一个16位的非负整数。

示例代码:

struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

// 将Socket绑定到8080端口
int ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (ret == -1) {
    perror("bind error");
    exit(EXIT_FAILURE);
}
  1. 监听Socket

当Socket绑定到端口上之后,需要将这个Socket转换成监听状态,等待客户端的连接。

示例代码:

// 开始监听客户端请求
int backlog = 10;
ret = listen(sockfd, backlog);
if (ret == -1) {
    perror("listen error");
    exit(EXIT_FAILURE);
}
  1. 接受连接

当有客户端连接请求到达服务器时,需要调用accept()函数接受连接请求,并创建新的Socket与客户端通信。

示例代码:

struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);

// 等待客户端的连接请求
int newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_addr_len);
if (newsockfd == -1) {
    perror("accept error");
    exit(EXIT_FAILURE);
}
  1. 读写Socket

在建立连接之后,客户端和服务器之间就可以通过Socket互相发送数据了。可以使用read()和write()函数进行数据读写。

示例代码:

// 从客户端读取数据
char buf[1024];
int n = read(newsockfd, buf, sizeof(buf));
if (n == -1) {
    perror("read error");
    exit(EXIT_FAILURE);
}

// 向客户端发送数据
const char* msg = "Hello, client!";
n = write(newsockfd, msg, strlen(msg));
if (n == -1) {
    perror("write error");
    exit(EXIT_FAILURE);
}
  1. 关闭Socket

在通信结束后,需要关闭Socket来释放资源。

示例代码:

// 关闭Socket
close(newsockfd);
close(sockfd);

示例:TCP服务器

下面是一个简单的TCP服务器示例代码,它可以监听8080端口,并将客户端发送来的字符串原样回发到客户端。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main() {
    // 创建Socket
    int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockfd == -1) {
        perror("socket error");
        exit(EXIT_FAILURE);
    }

    // 绑定到8080端口
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    int ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (ret == -1) {
        perror("bind error");
        exit(EXIT_FAILURE);
    }

    // 开始监听客户端请求
    int backlog = 10;
    ret = listen(sockfd, backlog);
    if (ret == -1) {
        perror("listen error");
        exit(EXIT_FAILURE);
    }

    // 循环等待客户端连接
    while (true) {
        // 等待客户端连接请求
        struct sockaddr_in client_addr;
        socklen_t client_addr_len = sizeof(client_addr);
        int newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_addr_len);
        if (newsockfd == -1) {
            perror("accept error");
            exit(EXIT_FAILURE);
        }

        // 从客户端读取字符串
        char buf[1024];
        int n = read(newsockfd, buf, sizeof(buf));
        if (n == -1) {
            perror("read error");
            exit(EXIT_FAILURE);
        }
        buf[n] = '\0';
        printf("Received message from client: %s\n", buf);

        // 回发字符串到客户端
        n = write(newsockfd, buf, n);
        if (n == -1) {
            perror("write error");
            exit(EXIT_FAILURE);
        }

        // 关闭连接
        close(newsockfd);
    }

    // 关闭Socket
    close(sockfd);

    return 0;
}

示例:TCP客户端

下面是一个简单的TCP客户端示例代码,它可以连接到127.0.0.1的8080端口,并向服务器发送一个字符串,并等待服务器回发字符串。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main() {
    // 创建Socket
    int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockfd == -1) {
        perror("socket error");
        exit(EXIT_FAILURE);
    }

    // 连接到服务器
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8080);
    inet_aton("127.0.0.1", &server_addr.sin_addr);
    int ret = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (ret == -1) {
        perror("connect error");
        exit(EXIT_FAILURE);
    }

    // 向服务器发送字符串
    const char* msg = "Hello, server!";
    int n = write(sockfd, msg, strlen(msg));
    if (n == -1) {
        perror("write error");
        exit(EXIT_FAILURE);
    }

    // 等待服务器回发字符串
    char buf[1024];
    n = read(sockfd, buf, sizeof(buf));
    if (n == -1) {
        perror("read error");
        exit(EXIT_FAILURE);
    }
    buf[n] = '\0';
    printf("Received message from server: %s\n", buf);

    // 关闭Socket
    close(sockfd);

    return 0;
}

以上就是C/C++ Linux Socket网络编程的简单流程以及两个示例代码的讲解。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C/C++ Linux Socket网络编程流程分析 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C#操作 JSON方法汇总

    C#是一种通用的编程语言,也是.NET框架的标准语言之一。许多开发者在使用C#开发项目时会经常使用JSON数据格式。操作JSON数据格式时,我们可以使用很多方法,下面介绍一下C#操作JSON数据的方法汇总。 1. 引用json.net库 在使用C#操作JSON数据时,可以使用第三方JSON库Newtonsoft.Json,该库是一个高性能的JSON框架,使用…

    C 2023年5月23日
    00
  • 如何使用devc++编写程序? devc++新建项目并编译运行的技巧

    请看下文。 如何使用devc++编写程序? 1. 安装devc++ 请先下载并安装devc++编译器,其官方网站为:https://sourceforge.net/projects/orwelldevcpp/。 2. 新建项目 在devc++中,打开该软件,并选择“文件”-“新建”-“项目”,然后在弹出的窗口中选择对应的项目类型,比如“控制台应用程序”,并在…

    C 2023年5月23日
    00
  • 基于C语言sprintf函数的深入理解

    基于C语言sprintf函数的深入理解攻略 sprintf函数是C语言中的一个字符串格式化函数。它可以将格式化的数据输出到目标字符串中。sprintf函数常常被用于将数字或者字符转化成字符串的场景中。在本篇攻略中,我们将从以下几个方面来深入理解sprintf函数: sprintf函数的语法及参数说明 格式化字符串的规则 实际使用示例 sprintf函数的语法…

    C 2023年5月22日
    00
  • JSON数据中存在单个转义字符“\”的处理方法

    处理 JSON 数据中存在单个转义字符“\”的方法有以下两种: 双反斜线转义为单斜线 当 JSON 数据中存在单个反斜线时,可以使用双反斜线转义为单斜线处理。示例如下: { "text": "这是一句包含反斜线\\的文本" } 可以通过代码将其转化为: { "text": "这是一句包含反…

    C 2023年5月23日
    00
  • c++非变易算法-stl算法

    当我们需要对一些数据集合进行一些固定的操作的时候,我们就可以使用STL(标准模板库)提供的算法来简化我们的代码并提高效率。STL算法主要包括三种,分别是变易算法、非变易算法和排序算法。其中,非变易算法指的是在执行算法的过程中不更改输入的数据集的内容。 在C++的STL库中,STL算法被封装在Algorithm头文件中。下面是一些常用的非变易算法: for_e…

    C 2023年5月22日
    00
  • C语言实现简单的学生学籍管理系统

    C语言实现简单的学生学籍管理系统攻略 本系统主要实现以下功能: 添加学生信息; 修改学生信息; 删除学生信息; 查询学生信息; 展示所有学生信息。 1. 添加学生信息 实现思路 添加学生信息需要以下步骤: 获取学生信息,包括姓名、性别、年龄等; 根据学生信息创建一个学生对象; 将学生对象添加到学生列表中。 示例代码 #include <stdio.h&…

    C 2023年5月23日
    00
  • 简单谈谈C++ 中指针与引用

    下面是关于C++中指针与引用的详细讲解: 指针与引用简介 在C++中,指针和引用都属于变量地址的概念,它们可以被用来实现对变量的间接访问。指针是一个变量,存储着另一个变量的地址,而引用则是一个别名,是被引用变量的另一个名称。 指针和引用都是C++中重要的概念,尤其是在使用函数传参和动态内存分配时,它们常被使用。 指针的使用 在C++中,可以使用指针来实现对另…

    C 2023年5月23日
    00
  • C++实现考勤管理系统

    C++实现考勤管理系统 简介 考勤管理系统是一种可以对员工的出勤情况进行统计和分析的工具,它可以帮助企业更加有效地管理其员工,并且提高员工出勤率。本文将介绍如何用C++实现考勤管理系统。 设计思路 考勤管理系统需要满足以下功能: 输入员工的考勤信息。 对员工的考勤记录进行存储和管理。 统计员工的出勤情况,并给出相应的报告。 为了实现这些功能,我们需要设计以下…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部