Advantages of sockets and standard I/o standard I/O functions
- With good portability
- Buffering can be used to improve performance
When you create a socket, the operating system generates I/O
a buffer for it. This buffer TCP
plays an important role in implementing the Protocol. If you use standard functions, you will get additional support for another buffer.
function buffering is to improve the transmission performance, socket buffer is to implement the Protocol, such as window control, retransmission and so on.
Performance improvements are considered in the following two ways:
- The amount of data transferred
- Number of times the data is buffered from the output
Disadvantages of the standard function:
- Not easy for two-way communication
- Sometimes you may use
fflush
functions frequently
- You need to
FILE
return the file descriptor as a struct pointer
Using standard I/O function pointer conversions
#include <stdio.h>FILE * fdopen(intconstchar// 将文件描述符转换为 FILE 结构体指针~ fildes: 文件描述符~ mode: 打开模式,读模式(r)和写模式(w)
FILE * fp;int fd = open("data.dat""w");...fclose(fp);
Convert to File descriptor
#include <stdio.h>int// 失败返回 -1
Socket-based standard I/O functions are used
echo_stdserv.c
echo_client.c
Benefits of I/O separation
As discussed earlier fork
, a file descriptor is copied from the calling function to differentiate between the file descriptors used in the input and output.
- Reduce the difficulty of coding implementation by separating the input process and the output process
- Input-independent output operation can increase speed
Create read mode FILE
and write mode FILE
pointers to separate the input and output tools.
- To
FILE
differentiate the pointer by read mode and write mode
- Reduced implementation Difficulty
I/O
improve performance by differentiating caches
Copying and semi-closing of file descriptors
The model following the conversion pointer to the same file descriptor FILE
is as follows:
Two pointers point to the same file descriptor, so calling a function on either FILE
pointer fclose
closes the file descriptor, which is the terminating socket.
The above situation is what we should avoid, then how to achieve semi-closure?
Just construct the following model:
Create pointers with their own file descriptors, because the socket is destroyed only after all file descriptors have been destroyed, which is guaranteed by the operating system.
When the write-mode pointer is closed, only the corresponding file descriptor can be destroyed and the socket cannot be destroyed.
This is still incomplete, as it can be done through the original file descriptor I/O
. Give a concrete implementation later.
Copy file descriptor
The replication and fork
function replication that are discussed here are different from the whole process, and what we want to do is to have different file descriptors for the same set of sockets in the same process.
#include <unistd.h>int dup(int fildes);int dup2(intint fildes2);~ fildes: 需要复制的文件描述符~ fildes2: 明确指定的文件描述符整数值
Detach the stream after copying the file descriptor
FILE * readfp;FILE * writefp;..."r""w");...fflush(writefp);shutdown(fileno(writefp), SHUT_ER); // 服务器进入半关闭状态,并向客户端发送EOF。调用该函数时,无论复制出多少文件描述符都将进入半关闭状态,同时传递EOF。
TCP/IP network programming (iv)