day-08 基于Linux的网络编程(套接字和标准I/O、分离I/O流、epoll、多线程服务器)

这篇具有很好参考价值的文章主要介绍了day-08 基于Linux的网络编程(套接字和标准I/O、分离I/O流、epoll、多线程服务器)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.套接字和标准 I/O

(一)标准 I/O 函数的优点

标准I/O函数(stdio)是在C语言中用于进行输入和输出操作的库函数。它们包括了一组标准的输入和输出函数,如printf、scanf、fopen、fclose等。标准I/O函数具有以下优点:

  1. 简单易用:标准I/O函数提供了简洁的接口,使得输入和输出操作变得简单易用。开发人员无需自行处理底层的文件或设备操作,而是直接使用高级的函数调用来完成输入和输出任务。

  2. 跨平台性:标准I/O函数是C语言的标准库函数,在不同的操作系统上都可以使用。这意味着编写的代码可以在不同的平台上进行移植,而无需对底层的操作系统接口进行修改。

  3. 缓冲机制:标准I/O函数通过使用内部缓冲区来提高输入和输出的效率。当从文件读取数据或向文件写入数据时,数据会首先存储在内部缓冲区中,然后才会实际读取或写入到文件中。这种缓冲机制可以减少对文件的频繁访问,提高了程序的性能。

  4. 格式化输入输出:标准I/O函数提供了格式化输入输出的功能,例如printf函数可以按照指定的格式将数据输出到终端或文件中,而scanf函数可以按照指定的格式从终端或文件中读取数据。这样可以方便地对输入输出进行格式控制,使得代码更加清晰和易读。

  5. 支持多种类型:标准I/O函数支持多种不同的数据类型进行输入和输出操作,包括整数、浮点数、字符串等。开发人员可以根据需要选择适合的函数来处理不同类型的数据,提高了灵活性和可扩展性。

总之,标准I/O函数具有简单易用、跨平台性、缓冲机制、格式化输入输出和多种类型支持等优点,是进行输入和输出操作的常用工具之一。但在某些情况下,如果需要更底层的控制或对性能要求较高,可能需要使用更低级别的I/O函数或系统调用。

在C++中,标准I/O函数(iostream)是用于进行输入和输出操作的库函数。它们包括了一组标准的输入和输出类,如std::cout、std::cin、std::ifstream、std::ofstream等。与C语言中的标准I/O函数相比,C++标准I/O函数具有以下优点:

  1. 面向对象:C++标准I/O函数是面向对象的,使用类和对象来进行输入和输出操作。这使得代码更加模块化和可扩展,可以通过继承和多态等特性实现更复杂的功能。

  2. 类型安全:C++标准I/O函数提供了类型安全的输入和输出操作。它们对不同的数据类型提供了适当的重载,以确保正确的数据转换和格式化输出。这可以避免潜在的类型错误和内存溢出问题。

  3. 重定向支持:C++标准I/O函数支持流的重定向,可以将输入和输出重定向到文件、字符串、网络套接字等不同的设备。这使得代码具有更大的灵活性,可以方便地实现日志记录、测试和调试等功能。

  4. 操作符重载:C++标准I/O函数通过运算符重载提供了更直观和简洁的语法。例如,可以使用<<运算符将数据输出到流中,使用>>运算符从流中读取数据。这使得代码更加易读和易写。

  5. 异常处理:C++标准I/O函数使用异常来处理错误和异常情况。当发生错误时,它们可以抛出适当的异常,从而提供更好的错误处理和异常处理机制。这有助于编写更健壮和可靠的代码。

总之,C++标准I/O函数具有面向对象、类型安全、重定向支持、操作符重载和异常处理等优点。它们提供了一种高级且方便的方式来进行输入和输出操作,适用于大多数网络编程和应用场景。然而,在某些特殊情况下,如果需要更底层的控制或对性能要求较高,可能需要使用更底层的网络库或系统调用。

(二)使用标准 I/O 函数

1.fdopen转换为 FILE 结构体指针

#include <iostream>
#include <cstdio>

int main() {
    int fd = open("example.txt", O_WRONLY | O_CREAT, 0666);  // 打开文件获取文件描述符
    if (fd == -1) {
        perror("Failed to open file");
        return 1;
    }

    FILE* filePtr = fdopen(fd, "w");  // 将文件描述符转换为FILE结构体指针
    if (filePtr == NULL) {
        perror("Failed to convert file descriptor");
        close(fd);
        return 1;
    }

    fprintf(filePtr, "Hello, World!");  // 使用标准I/O函数向文件中写入数据

    fclose(filePtr);  // 关闭文件指针
    return 0;
}

2.fileno  函数转换为文件描述符

#include <iostream>
#include <cstdio>

int main() {
    std::FILE* filePtr = std::fopen("example.txt", "r");  // 打开文件获取文件指针
    if (filePtr == nullptr) {
        perror("Failed to open file");
        return 1;
    }

    int fd = fileno(filePtr);  // 将文件指针转换为文件描述符

    // 使用文件描述符进行其他操作...

    std::fclose(filePtr);  // 关闭文件指针
    return 0;
}

3.iostream

通过使用 iostream,可以直接使用类似于 std::ifstream std::ofstream 的对象来进行文件的读写操作,无需显式地处理文件描述符。这样可以更好地利用 C++ 的面向对象特性,使代码更简洁、可读性更好,并且具有更好的类型安全性和异常处理机制。

#include <iostream>
#include <fstream>

int main() {
    std::ofstream file("example.txt");  // 打开文件进行写入操作

    if (!file) {
        std::cerr << "Failed to open file" << std::endl;
        return 1;
    }

    file << "Hello, World!";  // 向文件中写入数据

    file.close();  // 关闭文件

    std::ifstream inputFile("example.txt");  // 打开文件进行读取操作

    if (!inputFile) {
        std::cerr << "Failed to open file" << std::endl;
        return 1;
    }

    std::string content;
    inputFile >> content;  // 从文件中读取数据

    inputFile.close();  // 关闭文件

    std::cout << "Read from file: " << content << std::endl;

    return 0;
}

(三)基于套接字的标准 I/O 函数使用(C++ iostream)

注意:关联套接字和iostream仅适用于流式套接字,报文套接字和原始套接字需要用到相应的套接字API。

1.ios_server.cpp

 

2.ios_client.cpp

 

3.流式套接字 

流式套接字(stream socket)是一种在网络通信中常用的套接字类型,它提供了可靠的、基于字节流的双向数据传输

流式套接字使用TCP(Transmission Control Protocol)作为底层传输协议,它提供了以下特性:

  • 可靠性:TCP使用确认和重传机制来确保数据可靠地传输,以及流量控制和拥塞控制来调整发送速率。
  • 顺序性:TCP保证数据按照发送的顺序到达目标,不会发生乱序。
  • 面向连接:在进行数据传输之前,需要在客户端和服务器之间建立连接,通过三次握手来建立可靠的通信链路。
  • 全双工通信:流式套接字允许同时进行读取和写入操作,实现双向通信。
  • 高效性:TCP使用滑动窗口机制和缓冲区来优化数据传输效率。

使用流式套接字进行网络通信可以实现可靠的、面向连接的通信,适合对数据的完整性和顺序有严格要求的场景,如文件传输、视频流传输等。

在C++中,使用流式套接字进行网络通信通常会结合std::ostreamstd::istream类以及套接字API来进行输入输出操作。通过将套接字与iostream对象关联,可以使用C++标准库提供的高级输入输出函数和操作符来进行方便的数据传输。

4.报文套接字

报文套接字(datagram socket)和原始套接字(raw socket)是在网络通信中使用的两种特殊类型的套接字。

  • 报文套接字:报文套接字基于数据报协议(如UDP),它提供了一种无连接、不可靠的传输方式。通过报文套接字发送的数据以离散的数据报形式传输,每个数据报都包含了完整的目标地址和数据。报文套接字适用于那些不需要建立连接和保证可靠性的应用场景,如实时音视频传输、广播等。

在C++中,可以使用socket()函数创建一个报文套接字,并使用sendto()recvfrom()函数进行数据的发送和接收。

5.原始套接字

  • 原始套接字:原始套接字提供了对网络协议的底层访问,它允许应用程序通过自定义的协议头部来发送和接收数据。使用原始套接字,可以直接操作IP层、传输层或更低层的协议头部,实现更高级别的网络功能。原始套接字一般需要在特权模式(如管理员权限)下运行。

在C++中,可以使用socket()函数创建一个原始套接字,并使用sendto()recvfrom()函数进行数据的发送和接收。

需要注意的是,使用原始套接字需要谨慎,因为它可以绕过网络协议栈的一些安全机制,可能造成网络攻击或不当操作。在实际应用中,使用原始套接字需要具备足够的网络知识和相应的权限,并且应遵循相关的法律和规定。文章来源地址https://www.toymoban.com/news/detail-700365.html

(四)总结

二.分离 I/O 流

(一)分离 I/O 流

(二)文件描述符的复制和半关闭

(三)总结

三.优于select的epoll

(一)epoll 理解和应用

(二)条件触发和边缘触发

(三)总结

四.多线程服务器端的实现

(一)线程概念

(二)线程创建及运行

(三)线程存在的问题和临界区

(四)线程同步

(五)线程的销毁和多线程并发服务器端的实现

五.制作HTTP服务器端

到了这里,关于day-08 基于Linux的网络编程(套接字和标准I/O、分离I/O流、epoll、多线程服务器)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • linux【网络编程】之网络套接字预备

    在【网络基础】中我们提到了IP地址,接下来了解一下网络通信中其他方面的知识 端口号是一个2字节16位的整数; 端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来处理; 一个端口号只能被一个进程占用 通信原理 (公网)IP唯一标识一台主机,这样两台

    2024年02月05日
    浏览(91)
  • Linux网络编程(二-套接字)

    目录 一、背景知识 1.1 端口号 1.2 网络字节序 1.3 地址转换函数  二、Socket简介 三、套接字相关的函数  3.1 socket() 3.2 bind() 3.3 connect() 3.4 listen() 3.5 accept()  3.6 read()/recv()/recvfrom() 3.7 send()/sendto()  3.8 close()  四、UPD客服/服务端实验  1.1 端口号 端口号是访问服务器的标识 ,就好像

    2024年01月22日
    浏览(92)
  • 【Linux】网络编程套接字一

    上篇博客由唐僧的例子我们知道: 在IP数据包头部中,有两个IP地址,分别叫做源IP地址,和目的IP地址。 思考一下: 不考虑中间的一系列步骤,两台主机我们光有IP地址就可以完成通信了嘛? 想象一下发qq消息的例子,有了IP地址能够把消息发送到对方的机器上。 但是我们把

    2024年03月26日
    浏览(256)
  • 【Linux网络编程】网络编程套接字(TCP服务器)

    作者:爱写代码的刚子 时间:2024.4.4 前言:本篇博客主要介绍TCP及其服务器编码 只介绍基于IPv4的socket网络编程,sockaddr_in中的成员struct in_addr sin_addr表示32位 的IP地址 但是我们通常用点分十进制的字符串表示IP地址,以下函数可以在字符串表示和in_addr表示之间转换 字符串转in

    2024年04月14日
    浏览(79)
  • Linux网络编程——tcp套接字

    本章Gitee仓库:tcp套接字 客户端: 客户端: 关于构造和初始化,可以直接在构造的时候,将服务器初始化,那为什么还要写到 init 初始化函数里面呢? 构造尽量简单一点,不要做一些“有风险”的操作。 tcp 是面向连接的,通信之前要建立连接,服务器处于等待连接到来的

    2024年02月20日
    浏览(57)
  • 【Linux】网络基础+UDP网络套接字编程

    只做自己喜欢做的事情,不被社会和时代裹挟着前进,是一件很奢侈的事。 1. 首先计算机是人类设计出来提高生产力的工具,而人类的文明绵延至今一定离不开人类之间互相的协作,既然人类需要协作以完成更为复杂的工作和难题,所以计算机作为人类的工具自然也一定需要

    2024年02月08日
    浏览(63)
  • 【Linux】网络---->套接字编程(TCP)

    TCP的编程流程:大致可以分为五个过程,分别是准备过程、连接建立过程、获取新连接过程、消息收发过程和断开过程。 1.准备过程:服务端和客户端需要创建各自的套接字,除此之外服务端还需要绑定自己的地址信息和进行监听。注意:服务端调用listen函数后,处理监听状

    2024年02月04日
    浏览(67)
  • 【Linux网络】网络编程套接字(预备知识+UDP)

    目录 预备知识 1. 理解源IP地址和目的IP地址 2. 理解源MAC地址和目的MAC地址 3. 认识端口号  4. 理解源端口号和目的端口号 5. 端口号(port) vs 进程pid 6. 认识TCP协议和认识UDP协议 7. 网络字节序 socket编程接口  1. socket 常见API 2. sockaddr结构  简单的UDP网络程序  1. 服务端创建udp

    2024年02月19日
    浏览(58)
  • 【网络编程】网络编程概念,socket套接字,基于UDP和TCP的网络编程

    前言: 大家好,我是 良辰丫 ,今天我们一起来学习网络编程,网络编程的基本概念,认识套接字,UDP与TCP编程.💞💞💞 🧑个人主页:良辰针不戳 📖所属专栏:javaEE初阶 🍎励志语句:生活也许会让我们遍体鳞伤,但最终这些伤口会成为我们一辈子的财富。 💦期待大家三连,关注

    2023年04月20日
    浏览(61)
  • Linux网络编程- 原始套接字(Raw Socket)

    原始套接字(Raw Socket)提供了一种机制,允许应用程序直接访问底层传输协议,绕过操作系统提供的传输层接口。这种套接字通常用于实现新的协议或对现有协议进行低级别的操作。 以下是对原始套接字的详细介绍: 定义与用途 : 原始套接字是直接基于网络层(如IP)的。

    2024年02月07日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包