Hi Friends,
Today i'm "fighting" with a server and a client written in C.
These are the functions that i need to implement:
1) The client send a file to the server
2) The server launch a script on this file and answer to the client with the output file of the script
3) It should work on internet.
Now, that's the code of both:
CLIENT:
Code:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <signal.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <netdb.h>
#define PORT 7550
#define LENGTH 512
int main(int argc, char *argv[])
{
/* Variable Definition */
int sockfd;
int nsockfd;
char revbuf[LENGTH];
struct sockaddr_in remote_addr;
/* Get the Socket file descriptor */
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
{
printf("ERROR: Failed to obtain Socket Descriptor!\n");
return (0);
}
/* Fill the socket address struct */
remote_addr.sin_family = PF_INET;
remote_addr.sin_port = htons(PORT);
inet_pton(PF_INET, "127.0.0.1", &remote_addr.sin_addr);
bzero(&(remote_addr.sin_zero), 8);
/* Try to connect the remote */
if (connect(sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) == -1)
{
printf("ERROR: Failed to connect to the host!\n");
return (0);
}
else
printf("[Client] Connected to server at port %d...ok!\n", PORT);
/* Send File to Server */
if(!fork())
{
char* f_name = "/home/marcoraoul/Scrivania/quotidiani.txt";
char sdbuf[LENGTH];
printf("[Client] Sending %s to the Server...", f_name);
FILE *fp = fopen(f_name, "r");
if(fp == NULL)
{
printf("ERROR: File %s not found.\n", f_name);
exit(1);
}
bzero(sdbuf, LENGTH);
int f_block_sz;
int success = 0;
while((f_block_sz = fread(sdbuf, sizeof(char), LENGTH, fp))>0)
{
if(send(sockfd, sdbuf, f_block_sz, 0) < 0)
{
printf("ERROR: Failed to send file %s.\n", f_name);
break;
}
bzero(sdbuf, LENGTH);
}
printf("Ok File %s from Client was Sent!\n", f_name);
success = 1;
}
/* Receive File from Server */
printf("[Client] Receiveing file from Server and saving it as final.txt...");
char* f_name = "/home/marcoraoul/Scrivania/final.txt";
FILE *fp = fopen(f_name, "a");
if(fp == NULL)
printf("File %s Cannot be opened.\n", f_name);
else
{
bzero(revbuf, LENGTH);
int f_block_sz = 0;
int success = 0;
while(success == 0)
{
while(f_block_sz = recv(sockfd, revbuf, LENGTH, 0))
{
if(f_block_sz < 0)
{
printf("Receive file error.\n");
break;
}
int write_sz = fwrite(revbuf, sizeof(char), f_block_sz, fp);
if(write_sz < f_block_sz)
{
printf("File write failed.\n");
break;
}
else if(f_block_sz)
{
break;
}
bzero(revbuf, LENGTH);
}
printf("Ok received from server!\n");
success = 1;
fclose(fp);
}
}
close (sockfd);
printf("[Client] Connection lost.\n");
return (0);
}
SERVER:
Code:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <signal.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <netdb.h>
#define PORT 7550
#define BACKLOG 5
#define LENGTH 512
int main ()
{
/* Defining Variables */
int sockfd;
int nsockfd;
int num;
int sin_size;
struct sockaddr_in addr_local; /* client addr */
struct sockaddr_in addr_remote; /* server addr */
char revbuf[LENGTH]; // Receiver buffer
/* Get the Socket file descriptor */
if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1 )
{
printf("ERROR: Failed to obtain Socket Descriptor.\n");
return (0);
}
else
printf("[Server] Obtaining socket descriptor successfully.\n");
/* Fill the client socket address struct */
addr_local.sin_family = PF_INET; // Protocol Family
addr_local.sin_port = htons(PORT); // Port number
addr_local.sin_addr.s_addr = INADDR_ANY; // AutoFill local address
bzero(&(addr_local.sin_zero), 8); // Flush the rest of struct
/* Bind a special Port */
if( bind(sockfd, (struct sockaddr*)&addr_local, sizeof(struct sockaddr)) == -1 )
{
printf("ERROR: Failed to bind Port %d.\n",PORT);
return (0);
}
else
printf("[Server] Binded tcp port %d in SERVER-IP addr sucessfully.\n",PORT);
/* Listen remote connect/calling */
if(listen(sockfd,BACKLOG) == -1)
{
printf("ERROR: Failed to listen Port %d.\n", PORT);
return (0);
}
else
printf ("[Server] Listening the port %d sucessfully.\n", PORT);
int success = 0;
while(success == 0)
{
sin_size = sizeof(struct sockaddr_in);
/* Wait a connection, and obtain a new socket file despriptor for single connection */
if ((nsockfd = accept(sockfd, (struct sockaddr *)&addr_remote, &sin_size)) == -1)
{
printf("ERROR: Obtaining new Socket Despcritor.\n");
}
else
printf("[Server] Server has got connected from %s.\n", inet_ntoa(addr_remote.sin_addr));
/*Receive File from Client */
char* f_name = "/home/marcoraoul/Scrivania/receive.txt";
FILE *fp = fopen(f_name, "a");
if(fp == NULL)
printf("File %s Cannot be opened file on server.\n", f_name);
else
{
bzero(revbuf, LENGTH);
int f_block_sz = 0;
int success = 0;
while(success == 0)
{
while(f_block_sz = recv(nsockfd, revbuf, LENGTH, 0)) //could it be sockfd?
{
if(f_block_sz < 0)
{
printf("Error receiving file from client to server.\n");
break;
}
int write_sz = fwrite(revbuf, sizeof(char), f_block_sz, fp);
if(write_sz < f_block_sz)
{
printf("File write failed on server.\n");
break;
}
else if(f_block_sz)
{
break;
}
bzero(revbuf, LENGTH);
}
printf("Ok received from client!\n");
success = 1;
fclose(fp);
}
}
/* Call the Script */
system("chmod +x script.sh ; ./script.sh");
/* Send File to Client */
if(!fork())
{
char* f_name = "/home/marcoraoul/Scrivania/output.txt";
char sdbuf[LENGTH]; // Send buffer
printf("[Server] Sending %s to the Client...", f_name);
FILE *fp = fopen(f_name, "r");
if(fp == NULL)
{
printf("ERROR: File %s not found on server.\n", f_name);
exit(1);
}
bzero(sdbuf, LENGTH);
int f_block_sz;
while((f_block_sz = fread(sdbuf, sizeof(char), LENGTH, fp))>0)
{
if(send(nsockfd, sdbuf, f_block_sz, 0) < 0)
{
printf("ERROR: Failed to send file %s.\n", f_name);
break;
}
bzero(sdbuf, LENGTH);
}
printf(" Ok sent to client!\n");
success = 1;
close(nsockfd);
printf("[Server] Connection with Client closed. Server will wait now...\n");
while(waitpid(-1, NULL, WNOHANG) > 0);
}
}
}
THERE ARE 2 PROBLEMS:
1) Both of them don't receive the ENTIRE FILE but only a partition (regulated by the LENGHT parameter)... What can i do for solving the problem WITHOUT MODIFYING "LENGHT"? (the "while" before the "send" could be the problem... but i'm not sure...)
2) Substituting the IP address of my pc (the external one) in the line
Code:
inet_pton(PF_INET, "127.0.0.1", &remote_addr.sin_addr);
of client, server and client don't communicate... I have a router in my house, should i add something at the end of ip address, like "135.27.3.110:SOMETHING HERE!"? I also changed all af_inet in pf_inet...
I hope some of you can help me. Thank you so much.
Marco