- 论坛徽章:
- 0
|
- #ifndef SPLICE_H
- #define SPLICE_H
- #include <errno.h>
- #include <sys/uio.h>
- #include <sys/stat.h>
- #include <linux/unistd.h>
- #if defined(__i386__)
- #define __NR_sys_splice 313
- #define __NR_sys_tee 315
- #define __NR_sys_vmsplice 316
- #elif defined(__x86_64__)
- #define __NR_sys_splice 275
- #define __NR_sys_tee 276
- #define __NR_sys_vmsplice 278
- #elif defined(__powerpc__) || defined(__powerpc64__)
- #define __NR_sys_splice 283
- #define __NR_sys_tee 284
- #define __NR_sys_vmsplice 285
- #elif defined(__ia64__)
- #define __NR_sys_splice 1297
- #define __NR_sys_tee 1301
- #define __NR_sys_vmsplice 1302
- #else
- #error unsupported arch
- #endif
- #ifndef SPLICE_F_MOVE
- #define SPLICE_F_MOVE (0x01) /* move pages instead of copying */
- #define SPLICE_F_NONBLOCK (0x02) /* don't block on the pipe splicing (but */
- /* we may still block on the fd we splice */
- /* from/to, of course */
- #define SPLICE_F_MORE (0x04) /* expect more data */
- #define SPLICE_F_GIFT (0x08) /* pages passed in are a gift */
- #endif /* SPLICE_F_MOVE defined */
- /*
- * SPLICE_F_UNMAP was introduced later, so check for that seperately
- */
- #ifndef SPLICE_F_UNMAP
- #define SPLICE_F_UNMAP (0x10) /* undo vmsplice map */
- #endif
- static inline int ssplice(int fdin, loff_t *off_in, int fdout, loff_t *off_out,
- size_t len, unsigned int flags)
- {
-
- return syscall(__NR_sys_splice, fdin, off_in, fdout, off_out, len, flags);
- }
- static inline int stee(int fdin, int fdout, size_t len, unsigned int flags)
- {
- return syscall(__NR_sys_tee, fdin, fdout, len, flags);
- }
- static inline int svmsplice(int fd, const struct iovec *iov,
- unsigned long nr_segs, unsigned int flags)
- {
- return syscall(__NR_sys_vmsplice, fd, iov, nr_segs, flags);
- }
- #define SPLICE_SIZE (64*1024)
- #define BUG_ON(c) assert(!(c))
- #define min(x,y) ({ \
- typeof(x) _x = (x); \
- typeof(y) _y = (y); \
- (void) (&_x == &_y); \
- _x < _y ? _x : _y; })
- #define max(x,y) ({ \
- typeof(x) _x = (x); \
- typeof(y) _y = (y); \
- (void) (&_x == &_y); \
- _x > _y ? _x : _y; })
- static inline int error(const char *n)
- {
- perror(n);
- return -1;
- }
- static int __check_pipe(int pfd)
- {
- struct stat sb;
- if (fstat(pfd, &sb) < 0)
- return error("stat");
- if (!S_ISFIFO(sb.st_mode))
- return 1;
- return 0;
- }
- static inline int check_input_pipe(void)
- {
- if (!__check_pipe(STDIN_FILENO))
- return 0;
- fprintf(stderr, "stdin must be a pipe\n");
- return 1;
- }
- static inline int check_output_pipe(void)
- {
- if (!__check_pipe(STDOUT_FILENO))
- return 0;
- fprintf(stderr, "stdout must be a pipe\n");
- return 1;
- }
- #endif
复制代码- #include <time.h>
- #include <stdio.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <netdb.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <sys/epoll.h>
- #include <sys/types.h>
- #include <arpa/inet.h>
- #include <sys/ioctl.h>
- #include <sys/select.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <netinet/tcp.h>
- #include <sys/resource.h>
- #include "splice.h"
- #define DestPort 80
- int pipefd[2];
- // Support for non-blocking I/O
- static int set_nonblocking(const int sockfd)
- {
- int flags = 1;
- if (ioctl(sockfd, FIONBIO, &flags) && ((flags = fcntl(sockfd, F_GETFL, 0)) < 0 || fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0))
- {
- close(sockfd);
- return -1;
- }
- }
- int main(int argc, char *argv[])
- {
- char *ptr;
- fd_set readfds;
- struct timeval tv;
- char buffer[1024];
- int sockfd, efd, nbytes, nfds, i;
- char ch[] = "GET /opensource/2010/0422/528617.shtml HTTP/1.1\r\nAccept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\nAccept-Language: zh-cn\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)\r\nHost: news.chinaunix.net\r\nConnection: Keep-Alive\r\n\r\n";
- char server[] = "news.chinaunix.net";
- struct hostent *he;
- struct in_addr inadr;
- struct sockaddr_in dest_addr;
-
- long read_incoming, write_incoming, write_outcoming;
- int fp;
- if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- perror("socket");
- exit(1);
- }
-
- if (inet_aton(server, &inadr) == 0)
- {
- if ((he = gethostbyname(server)) == NULL)
- {
- printf("unable to resolve: %s\n", server);
- return (-1);
- }
- memcpy(&inadr.s_addr, he->h_addr_list[0], he->h_length);
- }
- dest_addr.sin_family = AF_INET;
- dest_addr.sin_port = htons(DestPort);
- // dest_addr.sin_addr.s_addr = inet_addr(DestIp);
-
- memcpy(&dest_addr.sin_addr, &inadr.s_addr, 4);
- // Create and setup the connection
- if (connect(sockfd, (struct sockaddr *)&dest_addr,sizeof(struct sockaddr)) == -1)
- {
- perror("connect");
- exit(1);
- }
- set_nonblocking(sockfd);
-
-
- nbytes = write(sockfd, ch, strlen(ch));
- printf("nbytes = %d\n", nbytes);
- fp = open("./chunked.html", O_WRONLY | O_CREAT | O_TRUNC, 0644);
-
- if ( pipe(pipefd) < 0 )
- {
- perror("pipe");
- exit(1);
- }
-
- do {
- read_incoming = ssplice(sockfd, NULL, pipefd[1], NULL, SPLICE_SIZE, SPLICE_F_NONBLOCK | SPLICE_F_MORE | SPLICE_F_MOVE);
- if(read_incoming < 0)
- {
- if(errno == EINTR || errno == EAGAIN)
- {
- usleep(100);
- continue;
- }
- error("1splice");
- break;
- }
- else if(read_incoming == 0)
- {
- break;
- }
- write_outcoming = read_incoming;
- while(write_outcoming > 0)
- {
- write_incoming = splice(pipefd[0], NULL, fp, NULL, write_outcoming, SPLICE_F_NONBLOCK | SPLICE_F_MORE | SPLICE_F_MOVE);
- if(write_incoming < 0)
- {
- if(write_incoming == -EAGAIN)
- {
- continue;
- }
- error("2splice");
- break;
- }
- write_outcoming -= write_incoming;
- }
- } while (1);
- close(fp);
- close(sockfd);
- }
复制代码 这个程序 作为http客户端,直接把socket数据 存储到磁盘中去。
在我的Ubuntu 就正常。
在CentOS 就报错1splice: Invalid argument
不知道什么原因? 各位大哥帮我看看
CentOS
Linux version 2.6.18-128.7.1.el5 (gcc version 4.1.2 20080704 (Red Hat 4.1.2-44)) #1 SMP Mon Aug 24 08:21:56 EDT 2009
Ubuntu
Linux version 2.6.31-14-generic-pae (buildd@rothera) (gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu ) #48-Ubuntu SMP Fri Oct 16 15:22:42 UTC 2009 |
|