Hi Folks
This is what i managed to write server.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
int main(int argc, char **argv)
{
int port = 9000; /* port number to use */
int sock; /* socket desciptor */
int desc; /* file descriptor for socket */
int in_fd; /* input file descriptor */
int out_fd; /* output file descriptor */
struct sockaddr_in addr; /* socket parameters for bind */
struct sockaddr_in addr1; /* socket parameters for accept */
int addrlen; /* argument to accept */
struct stat stat_buf; /* argument to fstat */
off_t offset = 0; /* file offset */
char filename[PATH_MAX]; /* filename to send */
int rc; /* holds return code of system calls */
/* check command line arguments, handling an optional port number */
if (argc == 2) {
port = atoi(argv[1]);
if (port <= 1024) { /* dont want root to run this :-) */
fprintf(stderr, "invalid port: %s\n", argv[1]);
exit(1);
}
} else if (argc != 1) {
fprintf(stderr, "usage: %s [port]\n", argv[0]);
exit(1);
}
/* create Internet domain socket */
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
fprintf(stderr, "unable to create socket: %s\n", strerror(errno));
exit(1);
}
/* fill in socket structure */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(port);
/* bind socket to the port */
rc = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
if (rc == -1) {
fprintf(stderr, "unable to bind to socket: %s\n", strerror(errno));
exit(1);
}
/* listen for clients on the socket */
rc = listen(sock, 1);
if (rc == -1) {
fprintf(stderr, "listen failed: %s\n", strerror(errno));
exit(1);
}
while (1) {
/* wait for a client to connect */
desc = accept(sock, (struct sockaddr *) &addr1, &addrlen);
if (desc == -1) {
fprintf(stderr, "accept failed: %s\n", strerror(errno));
exit(1);
}
/* get the file name from the client */
rc = recv(desc, filename, sizeof(filename), 0);
if (rc == -1) {
fprintf(stderr, "recv failed: %s\n", strerror(errno));
exit(1);
}
/* null terminate and strip any \r and \n from filename */
filename[rc] = '\0';
if (filename[strlen(filename)-1] == '\n')
filename[strlen(filename)-1] = '\0';
if (filename[strlen(filename)-1] == '\r')
filename[strlen(filename)-1] = '\0';
/* exit server if filename is "quit" */
if (strcmp(filename, "quit") == 0) {
fprintf(stderr, "quit command received, shutting down server\n");
break;
}
/* fprintf(stderr, "received request to send file %s\n", filename); */
/* open the file to be sent */
in_fd = open(filename, O_RDONLY);
if (in_fd == -1) {
fprintf(stderr, "unable to open '%s': %s\n", filename, strerror(errno));
exit(1);
}
/* get the size of the file to be sent */
fstat(in_fd, &stat_buf);
/* copy file using sendfile */
offset = 0;
rc = sendfile (desc, in_fd, &offset, stat_buf.st_size);
if (rc == -1) {
fprintf(stderr, "error from sendfile: %s\n", strerror(errno));
exit(1);
}
if (rc != stat_buf.st_size) {
fprintf(stderr, "incomplete transfer from sendfile: %d of %d bytes\n",
rc,
(int)stat_buf.st_size);
exit(1);
}
/* close descriptor for file that was sent */
close(in_fd);
/* close socket descriptor */
close(desc);
}
/* close socket */
close(sock);
return 0;
}
For the client part
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
int main (int argc, char** argv)
{
int src; /* file descriptor for source file */
int dest; /* file descriptor for destination file */
struct stat stat_buf; /* hold information about input file */
off_t offset = 0; /* byte offset used by sendfile */
int rc; /* return code from sendfile */
int port; /* port on the remote server to connect to */
struct sockaddr_in server; /* socket address */
int s ; /* client socket */
/* check for two command line arguments */
if (argc != 4) {
fprintf(stderr, "usage: %s <hostname> <port> <source> <destination> \n", argv[0]);
exit(1);
}
/* check command line arguments, handling an optional port number */
if (argc == 4) {
port = atoi(argv[1]);
if (port <= 1024) { /* dont want root to run this :-) */
fprintf(stderr, "invalid port: %s\n", argv[1]);
exit(1);
}
}
if ((he=gethostbyname(argv[1])) == NULL) { /* get the host info */
herror("gethostbyname");
exit(1);
}
strcpy( buf, "Hello there!"); /* create the message */
/* create stream socket using TCP */
fprintf(stderr, "Creating datagram socket.\n");
s = socket(AF_INET, SOCK_STREAM, 0);
if( s == -1 ) {
fprintf(stderr, "Socket was not created.\n");
exit(1);
}
else
fprintf(stderr, "Socket created successfully.\n");
server.sin_family = AF_INET; /* set up the server name */
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr( argv[1] );
/* connect to the server */
if( connect(s, &server, sizeof(server)) < 0) {
fprintf(stderr, "Failed to connect to socket.\n");
exit(1);
}
printf("Sending the message: %s\n", buf); /* send the message */
if( send(s, buf, sizeof(buf), 0) < 0 ) {
fprintf(stderr, "Failed to send data to socket.\n");
exit(1);
}
/* receive the echoed message from the server */
if( recv(s, buf, sizeof(buf), 0) < 0 ) {
fprintf(stderr, "Failed to receive data from socket.\n");
exit(1);
}
printf("The message from the server was: %s\n", buf);
close(s); /* close the socket */
printf("Client closed successfully\n"); /* successfully exit */
exit(0);
}
The problem i have now is what message the client should pass to the server ?
I just passed strcpy( buf, "Hello there!"); but i actually need to pass the file descriptor of the file which i need to get .
And when the server responds i need to copy that file to some path on the client.
I hope somebody helps me now .Please i have a feeling i am very close.
regards
Hrishy