Sends the contents of a file through a socket.
#include < sys/socket.h > ssize_t send_file(Socket_p, sf_iobuf, flags) int *Socket_p; struct sf_parms *sf_iobuf; uint_t flags;
The send_file subroutine sends data from the opened file specified in the sf_iobuf parameter, over the connected socket pointed to by the Socket_p parameter.
Note: Currently, the send_file only supports the TCP/IP protocol (SOCK_STREAM socket in AF_INET). An error will be returned when this function is used on any other types of sockets.
Socket_p | Points to the socket descriptor of the socket which the file will be sent
to.
Note: This is different from most of the socket functions. | ||||||||||||||||||
sf_iobuf | Points to a sf_parms structure defined as follows:
/* * Structure for the send_file system call */ #ifdef __64BIT__ #define SF_INT64(x) int64_t x; #define SF_UINT64(x) uint64_t x; #else #ifdef _LONG_LONG #define SF_INT64(x) int64_t x; #define SF_UINT64(x) uint64_t x; #else #define SF_INT64(x) int filler_##x; int x; #define SF_UINT64(x) int filler_##x; uint_t x; #endif #endif struct sf_parms { /* --------- header parms ---------- */ void *header_data; /* Input/Output. Points to header buf */ uint_t header_length; /* Input/Output. Length of the header */ /* --------- file parms ------------ */ int file_descriptor; /* Input. File descriptor of the file */ SF_UINT64(file_size) /* Output. Size of the file */ SF_UINT64(file_offset) /* Input/Output. Starting offset */ SF_INT64(file_bytes) /* Input/Output. number of bytes to send */ /* --------- trailer parms --------- */ void *trailer_data; /* Input/Output. Points to trailer buf */ uint_t trailer_length; /* Input/Output. Length of the trailer */ /* --------- return info ----------- */ SF_UINT64(bytes_sent) /* Output. number of bytes sent */ };
All fields marked with Input in the sf_parms structure requires setup by an application prior to the send_file calls. All fields marked with Output in the sf_parms structure adjusts by send_file when it successfully transmitted data, that is, either the specified data transmission is partially or completely done. The send_file subroutine attempts to write header_length bytes from the buffer pointed to by header_data, followed by file_bytes from the file associated with file_descriptor, followed by trailer_length bytes from the buffer pointed to by trailer_data, over the connection associated with the socket pointed to by Socket_p. As the data is sent, the kernel updates the parameters pointed by sf_iobuf so that if the send_file has to be called multiple times (either due to interruptions by signals, or due to non-blocking I/O mode) in order to complete a file data transmission, the application can reissue the send_file command without setting or re-adjusting the parameters over and over again. If the application sets file_offset greater than the actual file size, or file_bytes greater than (the actual file size - file_offset), the return value will be -1 with errno EINVAL. | ||||||||||||||||||
flags | Specifies the following attributes:
When the SF_CLOSE flag is set, the connected socket specified by Socket_p will be disconnected and closed by send_file after the requested transmission has been successfully done. The socket descriptor pointed to by Socket_p will be set to -1. This flag won't take effect if send_file returns non-0. The flag SF_REUSE currently is not supported by AIX. When this flag is specified, the socket pointed by Socket_p will be closed and returned as -1. A new socket needs to be created for the next connection. send_file will take advantage of a Network Buffer Cache in kernel memory to dynamically cache the output file data. This will help to improve the send_file performance for files which are:
Applications can exclude the specified file from being cached by using the SF_DONT_CACHE flag. send_file will update the cache every so often to make sure that the file data in cache is valid for a certain time period. The network option parameter "send_file_duration" controlled by the no command can be modified to configure the interval of the send_file cache validation, the default is 300 (in seconds). Applications can use the SF_SYNC_CACHE flag to ensure that a cache validation of the specified file will occur before the file is sent by send_file, regardless the value of the "send_file_duration". Other Network Buffer Cache related parameters are "nbc_limit", nbc_max_cache", and nbc_min_cache". For additional infromation, see the no command. |
There are three possible return values from send_file:
-1 | an error has occurred, errno contains the error code. |
0 | the command has completed successfully. |
1 | the command was completed partially, some data has been transmitted but the command has to return for some reason, for example, the command was interrupted by signals. |
The fields marked with Output in the sf_parms structure (pointed to by sf_iobuf) is updated by send_file when the return value is either 0 or 1. The bytes_sent field contains the total number of bytes that were sent in this call. It is always true that bytes_sent (Output) <= header_length(Input) + file_bytes(Input) + trailer_length (Input).
The send_file supports the blocking I/O mode and the non-blocking I/O mode. In the blocking I/O mode, send_file blocks until all file data (plus the header and the trailer) is sent. It adjusts the sf_iobuf to reflect the transmission results, and return 0. It is possible that send_file can be interrupted before the request is fully done, in that case, it adjusts the sf_iobuf to reflect the transmission progress, and return 1.
In the non-blocking I/O mode, the send_file transmits as much as the socket space allows, adjusts the sf_iobuf to reflect the transmission progress, and returns either 0 or 1. When there is no socket space in the system to buffer any of the data, the send_file returns -1 and sets errno to EWOULDBLOCK. select or poll can be used to determine when it is possible to send more data.
Possible errno returned: | |
---|---|
EBADF | Either the socket or the file descriptor parameter is not valid. |
ENOTSOCK | The socket parameter refers to a file, not a socket. |
EPROTONOSUPPORT | Protocol not supported. |
EFAULT | The addresses specified in the HeaderTailer parameter is not in a writable part of the user-address space. |
EINTR | The operation was interrupted by a signal before any data was sent. (If some data was sent, send_file returns the number of bytes sent before the signal, and EINTR is not set). |
EINVAL | The offset, length of the HeaderTrailer, or flags parameter is invalid. |
ENOTCONN | A send_file on a socket that is not connected, a send_file on a socket that has not completed the connect sequence with its peer, or is no longer connected to its peer. |
EWOULDBLOCK | The socket is marked non-blocking and the requested operation would block. |
ENOMEM | No memory is available in the system to perform the operation. |
PerformanceNote
By taking advantage of the Network Buffer Cache, send_file provides better performance and network throughput for file transmission. It is recommanded for files bigger than 4K bytes.
The connect subroutine, getsockopt subroutine, recv subroutine, recvfrom subroutine, recvmsg subroutine, select subroutine, sendmsg subroutine, sendto subroutine, setsockopt subroutine, shutdown subroutine, socket subroutine.
Sockets Overview and Understanding Socket Data Transfer in AIX Version 4.3 Communications Programming Concepts.