📄 sendn.c
字号:
/********************************************************************* Description: sendn.c* Provides a C file for the sendn function from the book Advanced* Programming in the UNIX Environment by Richard Stevens.* The sendn function calls the send function repeatedly until n bytes* have been written to the file descriptor.** Derived from a work by Fred Proctor & Will Shackleford** Author:* License: LGPL Version 2* System: Linux* * Copyright (c) 2004 All rights reserved.** Last change: * $Revision: 1.5 $* $Author: paul_c $* $Date: 2005/05/23 16:34:10 $********************************************************************/#include <string.h> /* strerror */#include <stdlib.h> /* memset() */#include <errno.h> /* errno */#include <math.h> /* fabs() */#include <sys/socket.h> /* send(), recv(), socket(), accept(), bind(), listen() */#include <sys/time.h> /* struct timeval */#include "sendn.h" /* sendn() */#include "rcs_print.hh" /* rcs_print_error() */#include "_timer.h" /* etime(), esleep() */int sendn_timedout = 0;int print_sendn_timeout_errors = 1;/* Write "n" bytes to a descriptor. */int sendn(int fd, const void *vptr, int n, int _flags, double _timeout){ int nleft; long nwritten; int select_ret; double start_time, current_time, timeleft; char *ptr; struct timeval timeout_tv; struct timeval timeout_tv_copy; fd_set send_fd_set; timeout_tv.tv_sec = (long) _timeout; timeout_tv.tv_usec = (long) (_timeout * 1000000.0); if (timeout_tv.tv_usec >= 1000000) { timeout_tv.tv_usec = timeout_tv.tv_usec % 1000000; } timeout_tv_copy = timeout_tv; FD_ZERO(&send_fd_set); FD_SET(fd, &send_fd_set); ptr = (char *) vptr; /* can't do pointer arithmetic on void* */ nleft = n; current_time = start_time = etime(); timeleft = _timeout; while (nleft > 0) { if (fabs(_timeout) > 1E-6) { if (_timeout > 0) { current_time = etime(); timeleft = start_time + _timeout - current_time; if (timeleft <= 0.0) { if (print_sendn_timeout_errors) { rcs_print_error ("sendn(fd=%d, vptr=%p, int n=%d, int flags=%d, double _timeout=%f) timed out.\n", fd, vptr, n, _flags, _timeout); } sendn_timedout = 1; return -1; } timeout_tv.tv_sec = (long) timeleft; timeout_tv.tv_usec = (long) (timeleft * 1000000.0); if (timeout_tv.tv_usec >= 1000000) { timeout_tv.tv_usec = timeout_tv.tv_usec % 1000000; } select_ret = select(fd + 1, (fd_set *) NULL, &send_fd_set, (fd_set *) NULL, &timeout_tv); } else { select_ret = select(fd + 1, (fd_set *) NULL, &send_fd_set, (fd_set *) NULL, NULL); } switch (select_ret) { case -1: rcs_print_error("Error in select: %d -> %s\n", errno, strerror(errno)); rcs_print_error ("sendn(fd=%d, vptr=%p, int n=%d, int _flags=%d, double _timeout=%f) failed.\n", fd, vptr, n, _flags, _timeout); return -1; case 0: rcs_print_error ("sendn(fd=%d, vptr=%p, int n=%d, int _flags=%d, double _timeout=%f) timed out.\n", fd, vptr, n, _flags, _timeout); return -1; default: break; } } if ((nwritten = send(fd, ptr, nleft, _flags)) == -1) { rcs_print_error("Send error: %d = %s\n", errno, strerror(errno)); return (-1); /* error */ } nleft -= nwritten; ptr += nwritten; if (nleft > 0 && _timeout > 0.0) { current_time = etime(); if (current_time - start_time > _timeout) { rcs_print_error("sendn: timed out after %f seconds.\n", current_time - start_time); return (-1); } esleep(0.001); } } rcs_print_debug(PRINT_SOCKET_WRITE_SIZE, "wrote %d bytes to %d\n", n, fd); return (n);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -