Linux IO模型漫谈(3) -- 阻塞式IO实现

简介:

在理解代码前有几个函数先说一下:

1 sockaddr_in 套接字地址结构

1
2
3
4
5
6
7
8
9
10
struct  sockaddr_in {
     uint8_t         sin_len;         //长度字段,这个sockaddr_in结构的长度,一般不用设置和检查它
     sa_family_t     sin_family;      //协议族,TCP,UDP等协议族就设置为AF_INET 
     in_port_t       sin_port;        //端口号
     
     struct  in_addr  sin_addr;        //32位的IPv4地址
     
     char             sin_zero(8);     //未使用
 
}

POSIX规范只需要指定其中的sin_family, sin_port, sin_addr三个字段

这个结构非常重要!!

2 socket函数(创建套接字)

#include <sys/socket.h>

int socket(int family, int type, int protocol)

参数解释:

family:协议族,和sockaddr_in中的sin_family一个意思

type: 指明套接字类型

Protocol:通常赋值为0

 

这个函数是所有套接字编程的入口,创建套接字。

3 htons函数

这个函数是将本地字节序列转换为网络字节序列,简单来说,就是将一个数的高低位互换

(如12 34 -> 3412)

这个函数在给servaddr_in赋值的时候会用到

下面这个程序包含了基本的IO操作,说明以注释的形式加在代码中;

服务器端:

#include <stdio.h>     //这个头包含了最简单的输入和输出
#include <sys/types.h>    //这个头包含了系统调用的大量数据结构
#include <sys/socket.h>   //这个头包含了socket的结构
#include <netinet/in.h>   //这个头包含了internet地址解析的一些数据结构
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int listenfd, portno;  //文件描述符
    int clifd, clilen;
    struct sockaddr_in serv_addr,cli_addr;  //socketadd_in定义在netinet/in.h中
    listenfd = socket(AF_INET, SOCK_STREAM, 0);  //创建一个套接字
    
    bzero((char *) &serv_addr, sizeof(serv_addr));  //初始化
    serv_addr.sin_family = AF_INET;     //设置协议族
    serv_addr.sin_port = htons(7777);      //设置端口
    serv_addr.sin_addr.s_addr = INADDR_ANY;  //设置socket的另一端的地址信息,由于这里是server程序,因此设置为ANY
    
    bind(listenfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); //绑定地址,将本地协议地址赋予一个套接字
    listen(listenfd, 5);  //监听socket,第二个参数规定了内核应该为相应套接字排队的最大连接数个数,不要设置为0
    
    clilen = sizeof(cli_addr);
    clifd = accept(listenfd, (struct sockaddr *) &cli_addr, &clilen); //当有客户端连接的时候,进入连接队列
    
    char buffer[256];
    bzero(buffer, 256);
    read(clifd, buffer, 255);   //读取客户端发送的消息
    printf("The Message is:%s\r\n", buffer);
    
    write(clifd, "I get the message", 17); //往客户端发送消息
    
    close(clifd);
    close(listenfd);
    return 0;

}

server的流程基本是这样的:

clip_image001

客户端:

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

int main(int argc, char* argv[])
{
    int socketfd;
    socketfd = socket(AF_INET, SOCK_STREAM, 0);
		
    struct sockaddr_in serv_addr;
		
    bzero((char *)&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(7777);
		
    connect(socketfd,(struct sockaddr *)  &serv_addr, sizeof(serv_addr));
		
    write(socketfd, "client message", 14);
		
    char buffer[256];
    bzero(buffer, 256);
    read(socketfd, buffer, 255);
		
    printf("server return message:%s\r\n", buffer);
		
    return 0;
}

客户端的流程如下;

clip_image002

目录
相关文章
|
7月前
|
Linux C++
|
7月前
|
存储 Java 芯片
BIO 阻塞IO流 数据存储
为了弄清楚 I/O 流 的执行原理,首先需要了解数据在磁盘中的存储方式。目前进行数据存储的磁盘分为两种:机械磁盘、固态硬盘。
|
6月前
|
Java Unix Linux
什么是阻塞IO和非阻塞IO
什么是阻塞IO和非阻塞IO
215 3
|
2月前
|
存储 缓存 算法
如何优化阻塞IO的性能?
【10月更文挑战第6天】如何优化阻塞IO的性能?
48 5
|
4月前
|
存储 Java 数据库连接
BIO阻塞IO流与数据存储大揭秘:性能与资源消耗,一文让你彻底解锁!
【8月更文挑战第25天】本文探讨了Java中BIO阻塞IO流与数据存储的概念及其实现。BIO作为一种传统IO模型,在处理每个客户端请求时需创建新线程并等待响应,这在并发量大时会导致性能下降和高资源消耗。示例代码展示了如何利用`ServerSocket`实现基于BIO的简单服务器。此外,文章还介绍了数据存储的基本方法,例如通过`BufferedWriter`向文件写入数据。两者对比显示,BIO适合连接数稳定的场景,而数据存储则适用于需要持久化保存信息的情况。通过这些分析和实例,希望能帮助读者更好地掌握这两种技术的应用场景及其优缺点。
48 0
|
4月前
|
C# 开发者 设计模式
WPF开发者必读:命令模式应用秘籍,轻松简化UI与业务逻辑交互,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,命令模式是简化UI与业务逻辑交互的关键技术,通过将请求封装为对象,实现UI操作与业务逻辑分离,便于代码维护与扩展。本文介绍命令模式的概念及实现方法,包括使用`ICommand`接口、`RelayCommand`类及自定义命令等方式,并提供示例代码展示如何在项目中应用命令模式。
53 0
|
4月前
|
Ubuntu Linux
内核实验(九):添加IO驱动的阻塞读写功能
本文通过修改内核模块代码,介绍了如何在Linux内核中为IO驱动添加阻塞读写功能,使用等待队列和条件唤醒机制来实现读写操作的阻塞和非阻塞模式,并在Qemu虚拟机上进行了编译、部署和测试。
20 0
|
5月前
|
Java
什么是阻塞IO?
**阻塞IO是一种IO操作模式,使得调用线程在IO未完成时会暂停,等待操作完成。简单但可能导致线程阻塞,适用于低并发、长处理场景。Java示例中,`ServerSocket`和`Socket`展示了这种模式。服务端接收到客户端连接后读取数据,回应&quot;Echo&quot;,每个连接需单独线程处理。高并发时可考虑非阻塞IO(NIO)或异步IO来优化。**
|
5月前
|
缓存 网络协议 算法
【Linux系统编程】深入剖析:四大IO模型机制与应用(阻塞、非阻塞、多路复用、信号驱动IO 全解读)
在Linux环境下,主要存在四种IO模型,它们分别是阻塞IO(Blocking IO)、非阻塞IO(Non-blocking IO)、IO多路复用(I/O Multiplexing)和异步IO(Asynchronous IO)。下面我将逐一介绍这些模型的定义:
248 2
阻塞IO、非阻塞IO和IO复用有啥区别?
阻塞IO、非阻塞IO和IO复用有啥区别?
140 1