一.套接字和标准 I/O
(一)标准 I/O 函数的优点
标准I/O函数(stdio)是在C语言中用于进行输入和输出操作的库函数。它们包括了一组标准的输入和输出函数,如printf、scanf、fopen、fclose等。标准I/O函数具有以下优点:
-
简单易用:标准I/O函数提供了简洁的接口,使得输入和输出操作变得简单易用。开发人员无需自行处理底层的文件或设备操作,而是直接使用高级的函数调用来完成输入和输出任务。
-
跨平台性:标准I/O函数是C语言的标准库函数,在不同的操作系统上都可以使用。这意味着编写的代码可以在不同的平台上进行移植,而无需对底层的操作系统接口进行修改。
-
缓冲机制:标准I/O函数通过使用内部缓冲区来提高输入和输出的效率。当从文件读取数据或向文件写入数据时,数据会首先存储在内部缓冲区中,然后才会实际读取或写入到文件中。这种缓冲机制可以减少对文件的频繁访问,提高了程序的性能。
-
格式化输入输出:标准I/O函数提供了格式化输入输出的功能,例如printf函数可以按照指定的格式将数据输出到终端或文件中,而scanf函数可以按照指定的格式从终端或文件中读取数据。这样可以方便地对输入输出进行格式控制,使得代码更加清晰和易读。
-
支持多种类型:标准I/O函数支持多种不同的数据类型进行输入和输出操作,包括整数、浮点数、字符串等。开发人员可以根据需要选择适合的函数来处理不同类型的数据,提高了灵活性和可扩展性。
总之,标准I/O函数具有简单易用、跨平台性、缓冲机制、格式化输入输出和多种类型支持等优点,是进行输入和输出操作的常用工具之一。但在某些情况下,如果需要更底层的控制或对性能要求较高,可能需要使用更低级别的I/O函数或系统调用。
在C++中,标准I/O函数(iostream)是用于进行输入和输出操作的库函数。它们包括了一组标准的输入和输出类,如std::cout、std::cin、std::ifstream、std::ofstream等。与C语言中的标准I/O函数相比,C++标准I/O函数具有以下优点:
-
面向对象:C++标准I/O函数是面向对象的,使用类和对象来进行输入和输出操作。这使得代码更加模块化和可扩展,可以通过继承和多态等特性实现更复杂的功能。
-
类型安全:C++标准I/O函数提供了类型安全的输入和输出操作。它们对不同的数据类型提供了适当的重载,以确保正确的数据转换和格式化输出。这可以避免潜在的类型错误和内存溢出问题。
-
重定向支持:C++标准I/O函数支持流的重定向,可以将输入和输出重定向到文件、字符串、网络套接字等不同的设备。这使得代码具有更大的灵活性,可以方便地实现日志记录、测试和调试等功能。
-
操作符重载:C++标准I/O函数通过运算符重载提供了更直观和简洁的语法。例如,可以使用<<运算符将数据输出到流中,使用>>运算符从流中读取数据。这使得代码更加易读和易写。
-
异常处理: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::ostream
和std::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
需要注意的是,使用原始套接字需要谨慎,因为它可以绕过网络协议栈的一些安全机制,可能造成网络攻击或不当操作。在实际应用中,使用原始套接字需要具备足够的网络知识和相应的权限,并且应遵循相关的法律和规定。文章来源地址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模板网!