当前位置:网站首页>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 :
边栏推荐
- POI excel 单元格换行
- [OBS] configFile in ini format of OBS
- Matlab extracts numerical data from irregular txt files (simple and practical)
- 如何让让别人畏惧你
- 2022-07-02: what is the output of the following go language code? A: Compilation error; B:Panic; C:NaN。 package main import “fmt“ func mai
- The role and necessity of implementing serializable interface
- 程序员的创业陷阱:接私活
- How to: configure ClickOnce trust prompt behavior
- Solutions of n-ary linear equations and their criteria
- 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?
猜你喜欢
Matlab extracts numerical data from irregular txt files (simple and practical)
Software testing redis database
Leetcode 46: full arrangement
【obs】obs的ini格式的ConfigFile
Application of high-precision indoor positioning technology in safety management of smart factory
Balance between picture performance of unity mobile game performance optimization spectrum and GPU pressure
Solve the problem that pycharm Chinese input method does not follow
进程与线程
Activity and fragment lifecycle
行业唯一!法大大电子合同上榜36氪硬核科技企业
随机推荐
如何:配置 ClickOnce 信任提示行为
Unity移动端游戏性能优化简谱之 画面表现与GPU压力的权衡
封装一个koa分布式锁中间件来解决幂等或重复请求的问题
How to become a senior digital IC Design Engineer (1-4) Verilog coding syntax: expression
Inexplicable problems in the nesting of constraintlayout and relativelayout
JGG专刊征稿:时空组学
高精度室内定位技术,在智慧工厂安全管理的应用
如何成为一名高级数字 IC 设计工程师(1-5)Verilog 编码语法篇:操作数
我对测试工作的一些认识(资深测试人员总结)
2021 postgraduate entrance examination mathematics 2 linear algebra
项目管理精华读书笔记(七)
2. Hal hardware abstraction layer
AIDL
[proteus simulation] 16 channel water lamp composed of 74hc154 four wire to 12 wire decoder
英特尔13代酷睿旗舰曝光,单核5.5GHz
redis那些事儿
今晚要修稿子準備發佈。但是,仍卡在這裡,也許你需要的是一個段子。
Touch and screen automatic rotation debugging
2021 reading summary (continuously updating)
搭建ADG后,实例2无法启动 ORA-29760: instance_number parameter not specified