当前位置:网站首页>Internet socket (non) blocking write/read n bytes
Internet socket (non) blocking write/read n bytes
2022-07-03 11:20:00 【Origin-yy】
Catalog
One 、 Blocking / Non blocking write and read Brief introduction
Two 、 Blocking / Non blocking write and read Read n Writing method of bytes
Four 、 Blocking wirte and read+ Overtime
2.I/O Multiplexing select()/poll():
select Blocking write+ Overtime :
select Blocking read+ Overtime :
3. Signal interruption blocks reading / Write
alarm() Blocking write Overtime
alarm() Blocking read Overtime
summary : Blocking plus timeout select It's over
5、 ... and 、timerfd Introduction to series of functions :
The following are in Internet Socket Under the write and read
One 、 Blocking / Non blocking write and read Brief introduction
(1)write
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t nbytes);1. Use description : It is expected that the user space buf Inside nbytes Bytes of data are copied to the file descriptor fd In the specified kernel buffer .
notes : Not sent to the opposite end socket, This is what the kernel does through the network ,write Write to kernel buffer , The kernel sends the data to the opposite end at some time through the network sockert In the peer kernel buffer specified by the file descriptor ,send It's the same thing , Not send .
2. Return value :
-1: Error and set errno.
=0: Connection is closed .
>0: Write data size .
When the buffer is enough to write all data , Write all and return the size .
When the buffer is not full enough to write , Write part first , Blocking write Will block until all writes , Non blocking will return the written data size . Return without blocking -1 also errno == EINTR( Signal interruption ) || errno == EWOULDBLOCK( Will block ) || errno == EAGAIN( No space to write ) when , Think the connection is normal .
EAGAIN, Prompt that your application has no data to read or space to write , Please try again later . stay VxWorks and Windows On ,EAGAIN Whose name is EWOULDBLOCK.
(2)read
#include <uinstd.h>
ssize_t read(int fd, void *buf, size_t nbytes);Use description : It is expected that the buffer in the kernel nbytes Bytes of data are copied to the user process space buf in .
notes : Not from the opposite end socket receive data , This is what the kernel does through the network , The kernel received the peer at some time socket Data sent ,read Read this data from the kernel buffer .recv It's the same thing , It's not receiving .
2. Return value :
-1, Error and set errno.
=0, Connection is closed .
>0, Read data size .
If there is data in the buffer , Are read away and return the size .
If there is no data in the buffer , In blocking mode read Will block waiting data , Non blocking , return -1, When errno == EINTR( Signal interruption ) || errno == EWOULDBLOCK( Will block ) || errno == EAGAIN( No data to read ) when , Think the connection is normal .
Two 、 Blocking / Non blocking write and read Read n Writing method of bytes
Blocking write write in n Bytes :
ssize_t writen(int fd, const void* buf,size_t n)
{
ssize_t numwriten;
size_t totwriten;
const char *p;
p = buf;
for(totwriten = 0; totwriten < n;)
{
numwriten = write(fd, p, n - totwriten);
if(numwriten <= 0)
{
if(numwriten == -1 && errno == EINTR)
continue;
else
return -1;
}
totwriten += numwriten;
p += numwriten;
}
return totwriten;
}Blocking read Read n Bytes :
ssize_t readn(int fd, void*buf,size_t n)
{
ssize_t numread;
size_t totread;
char *p;
p = buf;
for(totread = 0; totread < n;)
{
numread= read(fd, p, n - totread);
if(numread == 0)
return totread;
if(numread == -1)
{
if(errno == EINTR)
continue;
else
return -1;
}
totread += numread;
p += numread;
}
return totread;
}Non blocking write Write n Bytes :
int writen(int connfd, const void *buf, int nums) {
int left = 0;
int had = 0;
char *ptr = NULL;
if ((connfd <= 0) || (buf == NULL) || (nums < 0)) {
return -1;
}
ptr = (char *)buf;
left = nums;
int i = 0;
while (left > 0) {
had = write(connfd, ptr, left);
if (had == -1) {
if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) {
had = 0;
usleep(5);
if(i == 500)
return -1; // return -1 And errno by :EINTR EWOULDBLOCK EAGAIN It is timeout
else
i++;
} else {
return -1;
}
} else if (had == 0) {
return 0;
} else {
left -= had;
ptr += had;
}
}
return nums;
}Non blocking read Read n Bytes :
int readn(int fd, void *buf, int n) {
int left = 0;
int had = 0;
int *ptr = NULL;
ptr = (int *)buf;
left = n;
int i = 0;
while (left > 0) {
had = read(fd, (char *)ptr, left);
if (had == -1) {
if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) {
had = 0;
usleep(10);
if (i == 100)
return -1;
else
i++;
} else {
return -1;
}
} else if (had == 0) {
return 0;
} else {
left -= had;
ptr += had;
}
}
return n - left;
}3、 ... and 、send and recv
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buffer, size_t length, int flags);
ssize_t send(int sockfd, const void *buffer, size_t length, int flags);
( Detailed description in Linux/Unix System programming manual p1033)
The first three parameters and write、read equally , The fourth parameter is modified I/O The act of operating .
recv() Optional :MSG_DONTWAIT,MSG_OOB,MSG_PEEK,MSG_WAITALL.
MSG_WAITALL:
Usually ,recv() The number of bytes returned by the call is less than the number of bytes requested , And those bytes are actually still in the socket . It specifies MSG_WAITALL Marking will cause system call blocking , Until it's received length Bytes . however , Even if this flag is specified , When , The number of bytes returned by this call may still be less than the requested bytes . These situations are :
(a) Capture a signal ;
(b) The opposite end of the streaming socket terminated the connection ;
(c) Out of band data bytes encountered ;
(d) The message length received from the datagram socket is less than length Bytes ;
(e) An error occurred on the socket .
(MSG_WAITALL The tag can replace the above block readn() function , The difference lies in what we achieve readn() Functions are being
After the signal processing routine is interrupted, it will be called again .)
send() Optional :MSG_DONTWAIT,MSG_MORE,MSG_NOSIGNAL,MSG_OOB.
Four 、 Blocking wirte and read+ Overtime
1.setsocketopt:
#include <sys/socket.h>
int setsockopt( int socket, int level, int option_name,
const void *option_value, size_t ,ption_len);Parameters option_name:
SO_RCVTIMEO, Set read timeout . This option eventually assigns the receive timeout to sock->sk->sk_rcvtimeo.
SO_SNDTIMEO, Set the write timeout . This option will eventually assign the sending timeout to sock->sk->sk_sndtimeo.
After these two options are set , In case of overtime , return -1, And set up errno by EAGAIN or EWOULDBLOCK.
Get the timeout value
socklen_t optlen = sizeof(struct timeval);
struct timeval tv;
tv.tv_sec = 10;
tv.tv_usec = 0;
getsockopt(socketfd, SOL_SOCKET,SO_SNDTIMEO, &tv, &optlen);
Set the timeout value
socklen_t optlen = sizeof(struct timeval);
struct timeval tv;
tv.tv_sec = 10;
tv.tv_usec = 0;
setsockopt(socketfd, SOL_SOCKET, SO_RCVTIMEO, &tv, optlen);2.select/poll/epoll:
select() Blocking write+ Overtime :
int write_timeout(int fd, void *buf, size_t n, u_int32_t time) {
// Set timeout
fd_set wSet;
FD_ZERO(&wSet);
FD_SET(fd, &wSet);
struct timeval timeout;
memset(&timeout, 0, sizeof(timeout));
timeout.tv_sec = time;
timeout.tv_usec = 0;
// select Add timeout , Block and wait for write ready
int r;
while (1) {
r = select(fd + 1, NULL, &wSet, NULL, &timeout);
if (r < 0) {
if (errno == EINTR)
continue;
return r;
} else if (r == 0) {
errno = ETIMEDOUT; // Set up errno Timeout
return -1;
} else {
break;
}
}
// Open and write
int writeNum;
writeNum = write(fd, buf, n);
return writeNum;
}select Blocking read+ Overtime :
int read_timeout(int fd, void *buf, size_t n, u_int32_t time) {
// Set timeout
fd_set rSet;
FD_ZERO(&rSet);
FD_SET(fd, &rSet);
struct timeval timeout;
memset(&timeout, 0, sizeof(timeout));
timeout.tv_sec = time;
timeout.tv_usec = 0;
// select Plus timeout , And block waiting for read ready
int r;
while (1) {
r = select(fd + 1, &rSet, NULL, NULL, &timeout);
if (r < 0) {
if (errno == EINTR)
continue;
return r;
} else if (r == 0) {
errno = ETIMEDOUT;
return -1;
} else {
break;
}
}
// Open to read
int readnum;
readnum = read(fd, buf, n);
return readnum;
}select/poll/epoll It's thread safe , He provides a copy for each thread , There is a timeout
3. Signal interruption blocks reading / Write
alarm():
write/read It is a low-speed system call , During blocking , If you get a signal ,write/read Will be interrupted and will not continue , return -1, And will errono Set to EINTR. however , If it is read() Wait for system call , They are interrupted by the signal, which sometimes affects the correctness of the whole program , So some systems make such system calls restart automatically . Once interrupted by a signal , Restart immediately , So after restart, the blocking will still block . But by setting SA_INTERRUPT It can make read Do not restart after being interrupted by the signal , Return immediately .
alarm() Also known as alarm function , It can set a timer in the process , When the time specified by the timer expires , It sends SIGALRM The signal . Its default response mode is to terminate the call to alarm Process of function . It should be noted that , A process can only have one alarm time , Multithreaded scenarios are difficult to handle . If you're calling alarm The alarm time has been set before , Then any previous alarm clock time is replaced by a new value . call alarm(0) To cancel this alarm clock , And return the remaining time .
alarm() Accurate to seconds ,setitimer() Accurate to microseconds .
alarm() Blocking write Overtime
void handler(int s) {
printf("SIGALRM The signal arrives .\n");
return;
}
int write_timeout_alarm(int fd, void *buf, size_t n, u_int32_t time) {
struct sigaction act;
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_flags |= SA_INTERRUPT; // After setting this option , Interrupted system calls will not restart automatically
if (sigaction(SIGALRM, &act, NULL) == -1) {
perror("sigaction");
exit(-1);
}
alarm(time);
int readnum = write(0, buf, sizeof(buf)); // Read characters from standard input
alarm(0);
return readnum;
}alarm() Blocking read Overtime
void handler(int s) {
printf("SIGALRM The signal arrives .\n");
return;
}
int read_timeout_alarm(int fd, void *buf, size_t n, u_int32_t time) {
struct sigaction act;
act.sa_handler = handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
act.sa_flags |= SA_INTERRUPT; // After setting this option , Interrupted system calls will not restart automatically
if (sigaction(SIGALRM, &act, NULL) == -1) {
perror("sigaction");
exit(-1);
}
alarm(time);
int writenum = write(1, buf, sizeof(buf)); // Read characters from standard input
alarm(0);
return writenum;
}summary : Blocking plus timeout select() perhaps setsocketopt() It's over
5、 ... and 、timerfd Introduction to series of functions :
timerfd yes Linux Provides a timer interface for the user program . This interface is based on file descriptors , Timeout notification via readable event of file descriptor , It can be used read Get the number of timeouts since the last acquisition . For multiple timers , Can cooperate with select/poll/epoll Use .
#include <sys/timerfd.h>
int timerfd_create(int clockid, int flags);
// Create a timer object , Return refers to a file descriptor associated with it
int timerfd_settime(int fd, int flags, const struct itimerspec *new_value,
struct itimerspec *old_value);
// Set a new timeout , And start timing , Can start and stop timer ;
int timerfd_gettime(int fd, struct itimerspec *curr_value);
// Get the time remaining until the next timeout For details, see :
边栏推荐
- I, a tester from a large factory, went to a state-owned enterprise with a 50% pay cut. I regret it
- 面试题总结(2) IO模型,集合,NIO 原理,缓存穿透,击穿雪崩
- 项目管理精华读书笔记(六)
- ConstraintLayout跟RelativeLayout嵌套出现的莫名奇妙的问题
- 00后抛弃互联网: 毕业不想进大厂,要去搞最潮Web3
- Google Earth engine (GEE) -- when we use the front and back images to make up for the interpolation effect, what if there is no effect?
- Encapsulate a koa distributed locking middleware to solve the problem of idempotent or repeated requests
- Oracle 11g single machine cold standby database
- C语言日志库zlog基本使用
- Technical experts from large factories: how can engineers improve their communication skills?
猜你喜欢

Balance between picture performance of unity mobile game performance optimization spectrum and GPU pressure

How can UI automated testing get out of trouble? How to embody the value?

(二)进制

Probability theory: application of convolution in calculating moving average

活动预告 | 直播行业“内卷”,以产品力拉动新的数据增长点

The element form shows the relationship between elementary transformation and elementary matrix

高精度室内定位技术,在智慧工厂安全管理的应用

Expandablelistview that can expand and shrink (imitating the list page of professional selection of Zhilian recruitment)

EPS电动转向系统分析

AIDL
随机推荐
如何成为一名高级数字 IC 设计工程师(1-3)Verilog 编码语法篇:Verilog 行为级、寄存器传输级、门级(抽象级别)
IIS does not take effect after modifying the configuration information
Lecture 1 number field
Commonly used discrete random distribution
Google Earth Engine(GEE)——当我们前后影像来弥补插值效果得时候,没有效果怎么办?
How did I grow up in the past eight years as a test engineer of meituan? I hope technicians can gain something after reading it
Incremental database backup - DB incr DB full
【Proteus仿真】74HC154 四线转12线译码器组成的16路流水灯
AIDL
栈,单调栈,队列,单调队列
Analysis of JMM memory model
封装一个koa分布式锁中间件来解决幂等或重复请求的问题
Matlab extracts numerical data from irregular txt files (simple and practical)
Solve the problem that pycharm Chinese input method does not follow
Driver development based on I2C protocol
行业唯一!法大大电子合同上榜36氪硬核科技企业
asyncio 警告 DeprecationWarning: There is no current event loop
Oracle 11g single machine cold standby database
触摸与屏幕自动旋转调试
C语言日志库zlog基本使用