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函数(创建套接字)

1
2
3
#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操作,说明以注释的形式加在代码中;

服务器端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#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

客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#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






本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/archive/2012/06/04/2534178.html,如需转载请自行联系原作者

相关文章
|
18天前
|
存储 缓存 Linux
Linux IO的奥秘:深入探索数据流动的魔法
Linux I/O(输入/输出)系统是其核心功能之一,负责处理数据在系统内部及与外界之间的流动。为了优化这一流程,Linux进行了一系列努力和抽象化,以提高效率、灵活性和易用性。🚀
Linux IO的奥秘:深入探索数据流动的魔法
|
1月前
|
存储 监控 Linux
【Linux IO多路复用 】 Linux下select函数全解析:驾驭I-O复用的高效之道
【Linux IO多路复用 】 Linux下select函数全解析:驾驭I-O复用的高效之道
53 0
|
1月前
|
Linux C语言 SoC
嵌入式linux总线设备驱动模型分析
嵌入式linux总线设备驱动模型分析
32 1
|
2月前
|
监控 网络协议 Linux
Linux多路转接or多路复用模型
【2月更文挑战第5天】
36 1
|
5天前
|
机器学习/深度学习 缓存 监控
linux查看CPU、内存、网络、磁盘IO命令
`Linux`系统中,使用`top`命令查看CPU状态,要查看CPU详细信息,可利用`cat /proc/cpuinfo`相关命令。`free`命令用于查看内存使用情况。网络相关命令包括`ifconfig`(查看网卡状态)、`ifdown/ifup`(禁用/启用网卡)、`netstat`(列出网络连接,如`-tuln`组合)以及`nslookup`、`ping`、`telnet`、`traceroute`等。磁盘IO方面,`iostat`(如`-k -p ALL`)显示磁盘IO统计,`iotop`(如`-o -d 1`)则用于查看磁盘IO瓶颈。
|
17天前
|
Linux
Linux操作系统调优相关工具(三)查看IO运行状态相关工具 查看哪个磁盘或分区最繁忙?
Linux操作系统调优相关工具(三)查看IO运行状态相关工具 查看哪个磁盘或分区最繁忙?
21 0
|
1月前
|
消息中间件 Linux 调度
【Linux 进程/线程状态 】深入理解Linux C++中的进程/线程状态:阻塞,休眠,僵死
【Linux 进程/线程状态 】深入理解Linux C++中的进程/线程状态:阻塞,休眠,僵死
67 0
|
3天前
|
网络协议 Linux Shell
【linux网络(一)】初识网络, 理解四层网络模型
【linux网络(一)】初识网络, 理解四层网络模型
|
18天前
|
存储 缓存 安全
Linux IO:打开数据之窗的魔法
Linux I/O(输入/输出)是操作系统中一个至关重要的组成部分,它涉及到数据在内存🧠、存储设备💾、网络接口🌐等之间的传输过程。在Linux中,I/O操作不仅仅是文件读写那么简单,它包括了一系列复杂的机制和策略,旨在提高数据处理的效率,保证系统的稳定性和性能。📊
Linux IO:打开数据之窗的魔法