I'm trying to type a socket program that will allow me to transfer a file between a client and a server on two different computer, but it's not working. What's wrong with the code???
Server
Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
void sigusr1_handler(int sig)
{}
void sigchldhandler(int sig)
{
while (waitpid(-1,0,WNOHANG) > 0);
}
int main(int argc, char * argv[])
{
int serversockfd, clientsockfd, clientaddrlen, match;
struct sockaddr_in serveraddr, clientaddr;
struct sigaction act;
char buffer[1000];
char direction[4];
char filepath[100];
char * address=argv[1];
char * port=argv[2];
if(argc!=3)
{
printf("Incorrect number of arguments.");
exit(1);
}
/*defines handler for SIGCHLD to prevent zombie processes*/
act.sa_handler = sigchldhandler;
sigemptyset(&act.sa_mask);
act.sa_flags=SA_RESTART;
sigaction(SIGCHLD, &act, 0);
/*defines handler for SIGUSR1*/
act.sa_handler = sigusr1_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGUSR1, &act, NULL);
/*create server socket*/
serversockfd=socket(AF_INET, SOCK_STREAM, 0);
serveraddr.sin_family=AF_INET;
serveraddr.sin_addr.s_addr=inet_addr(address);
serveraddr.sin_port=atoi(port);
/*bind address to socket and listen for connections*/
bind(serversockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
listen(serversockfd, 5);
while(1)
{
printf("Waiting for connection...\n");
/*accept client connection*/
clientaddrlen=sizeof(clientaddr);
clientsockfd=accept(serversockfd,(struct sockaddr *)&clientaddr, &clientaddrlen);
printf("Connection accepted\n");
/*fork child process to allow multiple connections*/
if((fork())==0)
{
/*receive information from client regarding direction and filepath*/
printf("Server: Waiting for client's info\n");
int * clid, seid = getpid();
read(clientsockfd, clid, sizeof(clid));
write(clientsockfd,&seid,sizeof(seid));
read(clientsockfd, direction, sizeof(direction));
read(clientsockfd, filepath, sizeof(filepath));
printf("Server: Got info from client\n");
/*GET*/
if(strcmp(direction,"GET")==0)
{
printf("Server: Get\n");
FILE * in;
if((in=fopen(filepath, "r"))==NULL)
{
fprintf(stderr,"File does not exist");
char * err="Error: File did not exist on server.";
write(clientsockfd,err,strlen(err)+1);
exit(1);
}
while(fgets(buffer,sizeof(buffer), in)>0)
{
write(clientsockfd,buffer,strlen(buffer)+1);
kill((int)clid, SIGUSR2);
pause();
}
fclose(in);
}
/*PUT*/
else if(strcmp(direction,"PUT")==0)
{
printf("Server: Put\n");
FILE * out = fopen(filepath, "w");
while(match>0)
{
pause();
match = read(clientsockfd,buffer,sizeof(buffer));
fwrite(buffer, 1, strlen(buffer), out);
kill((int)clid, SIGUSR2);
}
fclose(out);
}
/*bad input*/
else
{
close(clientsockfd);
exit(1);
}
close(clientsockfd);
exit(0);
}
else
close(clientsockfd);
}
}
Client
Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <signal.h>
void sigusr2_handler(int sig)
{}
int main(int argc, char *argv[])
{
int sockfd;
char *match;
struct sockaddr_in serveraddr;
struct sigaction act;
char* addr = argv[1];
char* port = argv[2];
char* direction = argv[3]; /*GET or PUT*/
char* filepath = argv[4];
char buffer[1000];
/*defines handler for SIGUSR2*/
act.sa_handler = sigusr2_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGUSR1, &act, NULL);
if(argc!=5)
{
printf("Incorrect number of arguments");
exit(1);
}
sockfd=socket(AF_INET,SOCK_STREAM,0);
serveraddr.sin_family=AF_INET;
serveraddr.sin_addr.s_addr=inet_addr(addr);
serveraddr.sin_port=atoi(port);
if(connect(sockfd,(struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1)
{
perror("Connection failed\n");
exit(1);
}
/*FTP*/
/*sends to server GET or PUT and the filepath*/
printf("Client: Sending info to server\n");
int* seid, clid=getpid();
write(sockfd,&clid,sizeof(clid));
read(sockfd,seid,sizeof(seid));
write(sockfd,direction,strlen(direction)+1);
write(sockfd,filepath,strlen(filepath)+1);
printf("Client: Info sent\n");
/*GET*/
if(strcmp(direction,"GET")==0)
{
printf("Client: Get file\n");
FILE * out = fopen(filepath,"w");
while(read(sockfd, buffer, sizeof(buffer))>0)
{
pause();
fwrite(buffer, 1, strlen(buffer), out);
kill((int)seid, SIGUSR1);
}
fclose(out);
}
/*PUT*/
else if(strcmp(direction,"PUT")==0)
{
printf("Client: Put file\n");
FILE * in;
if((in=fopen(filepath, "r"))==NULL)
{
fprintf(stderr,"File does not exist.\n");
exit(1);
}
while(match!=NULL)
{
match = fgets(buffer, sizeof(buffer), in);
write(sockfd,buffer,strlen(buffer)+1);
kill((int)seid, SIGUSR1);
pause();
}
fclose(in);
}
else
{
perror("Invalid command\n");
close(sockfd);
exit(1);
}
close(sockfd);
exit(0);
}