2 * Server for the sendfile test program
3 * Syntax: testsf_s <own IP addr>
13 #include <sys/signal.h>
14 #include <netinet/in.h>
15 #include <sys/socket.h>
17 #define LISTEN_BACKLOG 10
38 struct sockaddr_in6 sa
, *ap
;
39 struct sockaddr_in6 from
;
41 struct addrinfo hints
;
46 int flags
, nonblocking
;
47 int nbytes
, flen
,gai
,count
;
55 if ((s
= socket(AF_INET6
, SOCK_STREAM
, 0)) < 0) {
56 printf("socket error = %d\n", errno
);
60 signal(SIGCHLD
, SIG_IGN
); /* ignore signals from children */
62 memset(&hints
, 0, sizeof(hints
));
63 hints
.ai_family
= PF_INET6
;
64 if ((gai
=getaddrinfo(argv
[1], NULL
, &hints
, &hp
))!=0) {
65 fprintf(stderr
, "Unknown subject address %s: %s\n",argv
[1], gai_strerror(gai
));
68 if (!hp
|| !hp
->ai_addr
|| hp
->ai_addr
->sa_family
!= AF_INET6
) {
69 fprintf(stderr
, "getaddrinfo failed");
74 /* server IP and port */
75 memcpy(&sa
, hp
->ai_addr
, hp
->ai_addrlen
);
77 sa
.sin6_port
= htons(port
);
79 /* bind IP and port to socket */
80 if ( bind(s
, (struct sockaddr_in6
*) &sa
, sizeof(sa
) ) < 0 ) {
81 printf("bind error = %d\n", errno
);
86 /* start to listen socket */
87 if ( listen(s
, LISTEN_BACKLOG
) < 0 ) {
88 printf("listen error = %d\n", errno
);
93 /* process connections */
95 /* accept a connection from a client */
97 if ((as
= accept(s
, &from
, &clen
)) < 0 ) {
98 printf("accept error = %d\n", errno
);
105 ap
= (struct sockaddr_in6
*)&from
;
107 /* create a process to manage the connection */
108 if ((pid
= fork()) < 0) {
109 printf("fork error = %d\n", errno
);
113 if (pid
> 0) { /* parent, go back to accept */
120 /* child process to manage a connection */
122 close(s
); /* close service socket */
124 /* get client request information */
125 if ((nbytes
= read(as
, rbuf
, 80)) <= 0) {
126 printf("socket read error = %d\n", errno
);
130 rbuf
[nbytes
] = '\0'; /* null terminate the info */
133 /* start with file length, '=' will start the filename */
137 while (*lp
!= '=') { /* convert ascii to integer */
143 flen
= strtol(number
, (char **)NULL
, 10);
144 printf("flen is %d.\n",flen
);
149 printf("The file to send is %s\n", lp
);
150 /* open requested file to send */
151 if ((fd
= open(lp
, O_RDONLY
)) < 0) {
152 printf("file open error = %d\n", errno
);
158 do { /* send file parts until EOF */
159 if ((rc
= sendfile(as
, fd
, offset
, flen
)) != flen
) {
160 if ((errno
!= EWOULDBLOCK
) && (errno
!= EAGAIN
)) {
161 printf("sendfile error = %d, rc = %d\n", errno
, rc
);
169 printf("File %s sent in %d parts\n", lp
, chunks
);
172 close(as
); /* close connection */
173 close(fd
); /* close requested file */
179 close(s
); /* close parent socket (never reached because of the while(1)) */