Question: How to enhance the capability of the server to support multiple clients at the same time?
Linux Design Philosophy: Everything is a File
What are files in Linux?
Chivalry:
- A physical file (logically related collection of data) in a file system
Broadly:
- devices, channels, memory, . . .
- Everything Linux manages
Understanding file descriptors
- The file descriptor is a non-negative integer, essentially a handle
- All resource identifiers that are transparent to users (programmers) can be regarded as handles
- The user interacts with the kernel using file descriptors (handles)
- The kernel operates the data structure of the corresponding resource through the file descriptor
The meaning of everything is a file
- Unify the operation methods of various devices (open, read, write, close)
Such as:
- IO devices (command line, display)
- Network equipment (NIC)
- ...
Programming Experiment: Manipulating the Command Line as a File
#include <stdio.h>
#include <unistd.h>
int main()
{
int iofd = 0;
char s[] = "D.T.SoftWare\n";
int len = 0;
write(iofd, s, sizeof(s));
len = read(0, s, 5);
s[len] = 0;
printf("%s\n", s);
return 0;
}
output:
book@100ask:~/Desktop$ ./a.out
D.T.SoftWare
12345
12345
book@100ask:~/Desktop$
...
book@100ask:~/Desktop$ ./a.out
D.T.SoftWare
12345678
12345 // 注意这里为什么只输出了 12345
book@100ask:~/Desktop$ 678 // 注意这里为什么输出 678
678: command not found
答:在 a.out 应用程序中输入了"12345678",但应用程序只读取了 5 个字符,即"12345"。当应用程序结束,a.out所在终端取得所有权,得到 "678", 并尝试将其当作命令解析
Classification of event-related functions
blocking function
- After the function is called, it needs to wait for an event to occur before returning
non-blocking function
- Can return in time after function call (only mark waiting events)
- After the event occurs, it is passed as a callback
Blocking vs Polling
- Polling refers to a method of sequentially accessing each relevant device to see if it needs service
- Polling can be used to solve the problem of blocking functions that prevent the program from continuing to execute
The magic select() function
- select() is used to monitor whether the specified file character generates events
- The target file can be detected by polling (the flag changes when the event occurs)
- Make specific processing according to the event type (eg: read data)
int select(int maxfd, // maxfd = n(最大的文件描述符 ) + 1,标记监听的描述符范围 [0 - maxfd-1]
fd_set *readset, // 检查可读性
fd_set *writeset, // 检查可写性
fd_set *exceptset, // 检查异常
const struct timeval *timeout); // 等待 IO 的时长
How to use the select() function
select() related data types and operations
fd_set 的每一位标识一个文件描述符,当某一位为 1,则表示监听
* FD_SERO(fd_set *fdset); // 将 fd_set 变量的所有位设置为0
* FD_SET(int fd, fd_set*fdset); // 在 fd_set 中指定要监听的 fd
* FD_CLR(int fd, fd_set*fdset); // 在 fd_set 中剔除 fd, 不再监听
* FD_ISSET(int fd, fd_set*fdset); // 在 fd_set 产看是否包含 fd
Programming experiment: select() first experience
#include <sys/select.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
int iofd = 0;
char s[] = "D.T.SoftWare";
int len = 0;
fd_set reads = {0};
fd_set temps = {0};
struct timeval timeout = {0};
FD_ZERO(&reads);
FD_SET(iofd, &reads);
while (1) {
int r = -1;
temps = reads; // NOTICE !!!
timeout.tv_sec = 0;
timeout.tv_usec = 50000;
r = select(1, &temps, 0, 0, &timeout);
if (r > 0) {
len = read(iofd, s, sizeof(s)-1);
s[len] = 0;
printf("Input: %s\n", s);
}
else if (r == 0) {
static int count = 0;
usleep(10000);
count++;
if (count > 100) {
printf("do something slse\n");
count = 0;
}
}
else {
break;
}
}
return 0;
}
output:
book@100ask:~/Desktop$ ./a.out
hello word
Input: hello word
do something slse
...
...
Thinking: Can the server-side functionality be extended using the select() function? If so, how to implement it?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。