LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-29-2012, 06:44 AM   #1
AscaL
LQ Newbie
 
Registered: Jun 2012
Posts: 7

Rep: Reputation: Disabled
TCP File Transfer in C with socket (server/client) on Linux. Help with code


Hello! Thank you in advance for reading this and possibly helping out.
I am trying to make a file transfer between server and client, but is working very badly. Basically what needs to happen is:
1) The client send a txt file to the server (i called it "quotidiani.txt")
2) The server saves it in another txt file ("receive.txt")
3) The server runs a script on it that modifies it and saves it with another name ("output.txt")
4) The server send the file back to the client that saves it (on the same socket) with the name ("final.txt")

The problem is that the first file (quotidiani.txt) is read just for a little part (I actually think i read just the first 512 bytes, not sure tho), and then there are some errors. I am not very proficient in C, what i wrote i found around on stack overflow and some other sites, and i read some tutorials and guides (like beej). I'd like someone to help me understand and correct my errors. I spent hours and hours on this but i can't find a solution...
To be totally clear, this IS a university project, and i'm not asking you to make it for me, but to point me to my errors in ways i can understand them (and correct them). As i said i'm not very good in C, but i want to get better.

The code for client is:
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 20000
#define LENGTH 512 


void error(const char *msg)
{
	perror(msg);
	exit(1);
}

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(AF_INET, SOCK_STREAM, 0)) == -1)
	{
	    error("ERROR: Failed to obtain Socket Descriptor!\n");
	}

	/* Fill the socket address struct */
	remote_addr.sin_family = AF_INET; 
	remote_addr.sin_port = htons(PORT); 
	inet_pton(AF_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)
	{
	    error("ERROR: Failed to connect to the host!\n");
	}
	else 
		printf("[Client] Connected to server at port %d...ok!\n", PORT);

	/* Send File to Server */
	//if(!fork())
	//{
		char* fs_name = "/home/aryan/Desktop/quotidiani.txt";
		char sdbuf[LENGTH]; 
		printf("[Client] Sending %s to the Server...", fs_name);
		FILE *fs = fopen(fs_name, "r");
		if(fs == NULL)
		{
		    printf("ERROR: File %s not found.\n", fs_name);
			exit(1);
		}

		bzero(sdbuf, LENGTH); 
		int fs_block_sz; 
		//int success = 0;
		while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs))>0)
	    {
	        if(send(sockfd, sdbuf, fs_block_sz, 0) < 0)
	        {
	            printf("ERROR: Failed to send file %s.\n", fs_name);
	            break;
	        }
	        bzero(sdbuf, LENGTH);
	    }
	    printf("Ok File %s from Client was Sent!\n", fs_name);
	    //success = 1;
	//}

	/* Receive File from Server */
	printf("[Client] Receiveing file from Server and saving it as final.txt...");
	char* fr_name = "/home/aryan/Desktop/progetto/final.txt";
	FILE *fr = fopen(fr_name, "a");
	if(fr == NULL)
		printf("File %s Cannot be opened.\n", fr_name);
	else
	{
	    bzero(revbuf, LENGTH); 
	    int fr_block_sz = 0;
	    int success = 0;
	    //while(success == 0)
	    //{
	        while(fr_block_sz = recv(sockfd, revbuf, LENGTH, 0))
	        {
	            if(fr_block_sz < 0)
	            {
	                error("Receive file error.\n");
	            }
	            int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
	            if(write_sz < fr_block_sz)
	            {
	                error("File write failed.\n");
	            }
				else if(fr_block_sz)
				{
					break;
				}
	            bzero(revbuf, LENGTH);
	        }
	        printf("Ok received from server!\n");
	        success = 1;
	        fclose(fr);
	    //}
	}
	close (sockfd);
	printf("[Client] Connection lost.\n");
	return (0);
}
The code for server is:

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 20000 
#define BACKLOG 5
#define LENGTH 512 

void error(const char *msg)
{
	perror(msg);
	exit(1);
}

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(AF_INET, SOCK_STREAM, 0)) == -1 )
	{
	    error("ERROR: Failed to obtain Socket Descriptor.\n");
	}
	else 
		printf("[Server] Obtaining socket descriptor successfully.\n");

	/* Fill the client socket address struct */
	addr_local.sin_family = AF_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 )
	{
	    error("ERROR: Failed to bind Port.\n");
	}
	else 
		printf("[Server] Binded tcp port %d in addr 127.0.0.1 sucessfully.\n",PORT);

	/* Listen remote connect/calling */
	if(listen(sockfd,BACKLOG) == -1)
	{
	    error("ERROR: Failed to listen Port.\n");
	}
	else
		printf ("[Server] Listening the port %d successfully.\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) 
		{
	        error("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* fr_name = "/home/aryan/Desktop/receive.txt";
		FILE *fr = fopen(fr_name, "a");
		if(fr == NULL)
			printf("File %s Cannot be opened file on server.\n", fr_name);
		else
		{
			bzero(revbuf, LENGTH); 
			int fr_block_sz = 0;
			//int success = 0;
			//while(success == 0)
			//{
			    while(fr_block_sz = recv(nsockfd, revbuf, LENGTH, 0)) //could it be sockfd?
			    {
			        if(fr_block_sz < 0)
			        {
			            error("Error receiving file from client to server.\n");
			        }
			        int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
			        if(write_sz < fr_block_sz)
			        {
			            error("File write failed on server.\n");
			        }
					else if(fr_block_sz)
					{
						break;
					}
			        bzero(revbuf, LENGTH);
			    }
			    printf("Ok received from client!\n");
			    fclose(fr);
			//}
		}

		/* Call the Script */
		system("cd ; chmod +x script.sh ; ./script.sh");

		/* Send File to Client */
	    //if(!fork())
	    //{
	        char* fs_name = "/home/aryan/Desktop/output.txt";
	        char sdbuf[LENGTH]; // Send buffer
	        printf("[Server] Sending %s to the Client...", fs_name);
	        FILE *fs = fopen(fs_name, "r");
	        if(fs == NULL)
	        {
	            printf("ERROR: File %s not found on server.\n", fs_name);
				exit(1);
	        }

	        bzero(sdbuf, LENGTH); 
	        int fs_block_sz; 
	        while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs))>0)
	        {
	            if(send(nsockfd, sdbuf, fs_block_sz, 0) < 0)
	            {
	                printf("ERROR: Failed to send file %s.\n", fs_name);
	                exit(1);
	            }
	            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);
	    //}
	}
}
I really think errors are mostly on the client.c. Any advice is very welcome too! Thanks a lot and have a nice day!
 
Old 06-29-2012, 07:57 AM   #2
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
In both your client and server code, you have the following statements:
Code:
else if(fr_block_sz)
{
    break;
}
You probably do not want this. Instead, you want to loop again so that you can perform another recv() call. Perhaps this code was left over from a previous version of your code where the outer while-loop was not commented out?
 
1 members found this post helpful.
Old 06-29-2012, 08:24 AM   #3
AscaL
LQ Newbie
 
Registered: Jun 2012
Posts: 7

Original Poster
Rep: Reputation: Disabled
Mmmmm I'm not 100% sure, but that should be there because the recv() can return 0 (since i handle the > and < 0). Why isn't that useful? I'm asking because i tried to do a lot of tests, and that's why the outer while is commented, and i'm not finding any difference with it commented or not (the outer while).
For what i understand (probably is wrong, but still) what should happen is this:
Code:
while(fr_block_sz = recv(nsockfd, revbuf, LENGTH, 0))
store result of recv() in fr_block_sz
Code:
if(fr_block_sz < 0)
if recv bytes are < 0 is an error
Code:
int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr); 
if(write_sz < fr_block_sz)
write from buffer to file fr_block_sz bytes, then check is the bytes written are same as fr_b_s. if not is another error
Code:
else if(fr_block_sz)
if fr_b_s is 0 then it breaks the loop because writing 0 bytes = nothing more to write.

That's how i got it, but I might very well be wrong.

And thanks for the comment!
 
Old 06-29-2012, 09:20 AM   #4
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
If fr_block_sz is 0, then the condition below evaluates to false, not true as you are thinking. If fr_block_sz is either -1 or greater than 0, then the statement evaluates to true:
Code:
else if(fr_block_sz)
recv() can return some number N that is either -1, 0, or some number greater than 0. A -1 implies an error, but not necessarily one that requires you to give up on receiving. Check the value of errno; if it is equal to EWOULDBLOCK (or EAGAIN) or EINTR then you may want to try calling recv() again.

When a server is receiving data from a client, and a result of 0 is returned, this is a good clue that the client has disconnected. Obviously when N is greater than 0, then data has been successfully received.

My earlier comment was based on the initial code you presented; when N is not equal to zero, the condition you had programmed will evaluate to true, and thus you will exit the while-loop. The while-loop that is commented out has no bearing on the program you were executing. Thus your server performed one successful recv(), then wrote some data to a file, and then exited the while-loop. I do not think this is what you wanted.

Last edited by dwhitney67; 06-29-2012 at 10:08 AM.
 
1 members found this post helpful.
Old 06-29-2012, 09:51 AM   #5
AscaL
LQ Newbie
 
Registered: Jun 2012
Posts: 7

Original Poster
Rep: Reputation: Disabled
It definitively is not. I think you might have helped a lot, i'm gonna do some tries and get back with what i find. Thanks a lot!
 
Old 06-29-2012, 11:29 AM   #6
AscaL
LQ Newbie
 
Registered: Jun 2012
Posts: 7

Original Poster
Rep: Reputation: Disabled
Hey, thanks a lot that really helped me! I'm stuck with something else now tho.
I changed both server and client code to this:

server:
Code:
/*Receive File from Client */
		char* fr_name = "/home/aryan/Desktop/receive.txt";
		FILE *fr = fopen(fr_name, "a");
		if(fr == NULL)
			printf("File %s Cannot be opened file on server.\n", fr_name);
		else
		{
			bzero(revbuf, LENGTH); 
			int fr_block_sz = 0;
		    while((fr_block_sz = recv(nsockfd, revbuf, LENGTH, 0)) >= 0) 
		    {
				if (fr_block_sz == 0) 
				{
					break;
				}
		        int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
				if(write_sz < fr_block_sz)
		        {
		            error("File write failed on server.\n");
		        }
				bzero(revbuf, LENGTH);
			}
			if(fr_block_sz < 0)
	        {
	            error("Error receiving file from client to server.\n");
	        }
			printf("Ok received from client!\n");
			fclose(fr); 
		}
Client:

Code:
/* Receive File from Server */
	printf("[Client] Receiveing file from Server and saving it as final.txt...");
	char* fr_name = "/home/aryan/Desktop/progetto/final.txt";
	FILE *fr = fopen(fr_name, "a");
	if(fr == NULL)
		printf("File %s Cannot be opened.\n", fr_name);
	else
	{
	    bzero(revbuf, LENGTH); 
	    int fr_block_sz = 0;
	        while((fr_block_sz = recv(sockfd, revbuf, LENGTH, 0)) >= 0)
	        {
				if (fr_block_sz == 0) 
				{
					break;
				}
	            int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
	            if(write_sz < fr_block_sz)
				{
	                error("File write failed.\n");
	            }
				bzero(revbuf, LENGTH);
			}
			if(fr_block_sz < 0)
            {
                error("Receive file error.\n");
            }
	        printf("Ok received from server!\n");
	        fclose(fr);
	}
And now the first file get sent completely and the script works on it. The problem is that to send this first file i have to ^C (terminate) the client process... i don't know why but if i don't ^C it just keep being stuck. As soon as i do that it starts transferring the file and running the script.
Thanks again i've been stuck for days on that thing!
 
Old 06-29-2012, 12:20 PM   #7
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
The recv() call in your client blocks until there is data to be read. One way to mitigate the blocking is to setup the socket to be, well, non-blocking. However this presents issues such as I described earlier, where recv() may return -1 but errno indicates EWOULDBLOCK (which is the same as EAGAIN). This is not an error, but merely an indicator that there is nothing to read.

One way to avoid blocking on recv() is to not call that function unless you know that there is indeed something to be read on the socket. You can check the socket using select(). If you provide it a timeout period, the client can avoid being locked up.

A third alternative is to set a "receive timeout" on the socket; you can do this like this:
Code:
struct timeval timeout = {5, 0};
if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (const void*) &timeout, sizeof(timeout)) < 0)
{
    fprintf(stderr, "Error configuring socket for rcv-timeout (errno = %d)\n", errno);
}
If after 5 seconds, there is no data to receive, the recv() will unblock and return a -1 (it's been a while since I've worked with this, so the -1 is a guess; it may return 0).
 
1 members found this post helpful.
Old 06-29-2012, 12:45 PM   #8
AscaL
LQ Newbie
 
Registered: Jun 2012
Posts: 7

Original Poster
Rep: Reputation: Disabled
First of all, thank you very very much. You have been immensely(?) helpful.

I'm not completely getting it... Basically the recv() blocks the client until there is data to be read, so since it has to send first it can't send? But isn't the send called first in the client? (client->server->script->server->client). Does this work for the server too? (do i have to make the server non-blocking too?).

As for the select() i'm reading it now, and it seems awfully complex to set up (or i just suck at this), not that it can't be done, just seem complicated.

I'm looking at the setsockopt too, and this seems like something i can set up, but i am not getting where should i put it (probably the answer lies in my first question).
Anyway this is the return value for setsockopt (incase u care)

Upon successful completion, setsockopt() shall return 0. Otherwise, -1 shall be returned and errno set to indicate the error.

I'm gonna read it now so i can try to understand better. Thanks a lot! (again).
 
Old 06-29-2012, 02:17 PM   #9
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by AscaL View Post
I'm looking at the setsockopt too, and this seems like something i can set up, but i am not getting where should i put it (probably the answer lies in my first question).
You call setsockopt() after you have created the socket. For example:
Code:
...
    int sd = socket(AF_INET, SOCK_STREAM, 0);

    if (sd > 0)
    {
        struct timeval timeout = {5, 0};

        if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (const void*) &timeout, sizeof(timeout)) < 0)
        {
            fprintf(stderr, "Error configuring socket for rcv-timeout (errno = %d)\n", errno);
            return -1;
        }

        /*... connect to server ... */

        /* receive data */
        char buf[1024];
        int  ret = 0;

        do
        {
            ret = recv(sd, buf, sizeof(buf), 0);

            if (ret < 0)
            {
                if (errno == EAGAIN)
                {
                    printf("recv() timed out.\n");
                }
                else
                {
                    fprintf(stderr, "recv() failed due to errno = %d\n", errno);
                }
            }
        } while (ret >= 0);
    }
...
 
1 members found this post helpful.
Old 06-29-2012, 03:01 PM   #10
AscaL
LQ Newbie
 
Registered: Jun 2012
Posts: 7

Original Poster
Rep: Reputation: Disabled
Hey, I implemented (ok, i copied) the setsockopt the same way it is in the example (and again, thanks).
That's what happens:
case 1: with fork()
I start the client and server. After 5 sec i get this:
Code:
[Client] Connected to server at port 20000...ok!
[Client] Sending /home/aryan/Desktop/quotidiani.txt to the Server...Ok File /home/aryan/Desktop/quotidiani.txt from Client was Sent!
[Client] Receiveing file from Server and saving it as final.txt...recv() timed out.
[Client] Receiveing file from Server and saving it as final.txt...recv() timed out. (Since client closes i don't receive this obviusly)
Ok received from server!
Ok received from server!
[Client] Connection lost.
[Client] Connection lost. (And it closes)
and then the server receive the file from client, apply the script and hangs waiting.
case 2: without fork()
Since there were 2 [Client] messages i tought of eliminating the fork, the result is basically the same:
Code:
[Client] Connected to server at port 20000...ok!
[Client] Sending /home/aryan/Desktop/quotidiani.txt to the Server...Ok File /home/aryan/Desktop/quotidiani.txt from Client was Sent!
[Client] Receiveing file from Server and saving it as final.txt...recv() timed out.
Ok received from server!
[Client] Connection lost.
Also, i tried commenting the close(sockfd); hoping that the client would not exit, but it does, so i guess there is an error of some kind.

I'm happy this is now kinda working (well is getting better atleast) but the client still closes, whether i do it manually or with the sockopt...And I don't get where is the error!
This thing is driving me crazy :S
 
Old 06-29-2012, 04:24 PM   #11
AscaL
LQ Newbie
 
Registered: Jun 2012
Posts: 7

Original Poster
Rep: Reputation: Disabled
So, I HAVE DONE IT!!!
Thank you dwhitney67 this wouldn't have been possible without you!

So, for anyone who cares about this (anyone?... so much silence) i'll post the source codes.
Thank you again!

client.c:

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 20000
#define LENGTH 512 


void error(const char *msg)
{
	perror(msg);
	exit(1);
}

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(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		fprintf(stderr, "ERROR: Failed to obtain Socket Descriptor! (errno = %d)\n",errno);
		exit(1);
	}

	/* Fill the socket address struct */
	remote_addr.sin_family = AF_INET; 
	remote_addr.sin_port = htons(PORT); 
	inet_pton(AF_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)
	{
		fprintf(stderr, "ERROR: Failed to connect to the host! (errno = %d)\n",errno);
		exit(1);
	}
	else 
		printf("[Client] Connected to server at port %d...ok!\n", PORT);

	/* Send File to Server */
	//if(!fork())
	//{
		char* fs_name = "/home/aryan/Desktop/quotidiani.txt";
		char sdbuf[LENGTH]; 
		printf("[Client] Sending %s to the Server... ", fs_name);
		FILE *fs = fopen(fs_name, "r");
		if(fs == NULL)
		{
			printf("ERROR: File %s not found.\n", fs_name);
			exit(1);
		}

		bzero(sdbuf, LENGTH); 
		int fs_block_sz; 
		while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs)) > 0)
		{
		    if(send(sockfd, sdbuf, fs_block_sz, 0) < 0)
		    {
		        fprintf(stderr, "ERROR: Failed to send file %s. (errno = %d)\n", fs_name, errno);
		        break;
		    }
		    bzero(sdbuf, LENGTH);
		}
		printf("Ok File %s from Client was Sent!\n", fs_name);
	//}

	/* Receive File from Server */
	printf("[Client] Receiveing file from Server and saving it as final.txt...");
	char* fr_name = "/home/aryan/Desktop/progetto/final.txt";
	FILE *fr = fopen(fr_name, "a");
	if(fr == NULL)
		printf("File %s Cannot be opened.\n", fr_name);
	else
	{
		bzero(revbuf, LENGTH); 
		int fr_block_sz = 0;
	    while((fr_block_sz = recv(sockfd, revbuf, LENGTH, 0)) > 0)
	    {
			int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
	        if(write_sz < fr_block_sz)
			{
	            error("File write failed.\n");
	        }
			bzero(revbuf, LENGTH);
			if (fr_block_sz == 0 || fr_block_sz != 512) 
			{
				break;
			}
		}
		if(fr_block_sz < 0)
        {
			if (errno == EAGAIN)
			{
				printf("recv() timed out.\n");
			}
			else
			{
				fprintf(stderr, "recv() failed due to errno = %d\n", errno);
			}
		}
	    printf("Ok received from server!\n");
	    fclose(fr);
	}
	close (sockfd);
	printf("[Client] Connection lost.\n");
	return (0);
}
server.c:

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 20000 
#define BACKLOG 5
#define LENGTH 512 

void error(const char *msg)
{
	perror(msg);
	exit(1);
}

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(AF_INET, SOCK_STREAM, 0)) == -1 )
	{
		fprintf(stderr, "ERROR: Failed to obtain Socket Descriptor. (errno = %d)\n", errno);
		exit(1);
	}
	else 
		printf("[Server] Obtaining socket descriptor successfully.\n");

	/* Fill the client socket address struct */
	addr_local.sin_family = AF_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 )
	{
		fprintf(stderr, "ERROR: Failed to bind Port. (errno = %d)\n", errno);
		exit(1);
	}
	else 
		printf("[Server] Binded tcp port %d in addr 127.0.0.1 sucessfully.\n",PORT);

	/* Listen remote connect/calling */
	if(listen(sockfd,BACKLOG) == -1)
	{
		fprintf(stderr, "ERROR: Failed to listen Port. (errno = %d)\n", errno);
		exit(1);
	}
	else
		printf ("[Server] Listening the port %d successfully.\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) 
		{
		    fprintf(stderr, "ERROR: Obtaining new Socket Despcritor. (errno = %d)\n", errno);
			exit(1);
		}
		else 
			printf("[Server] Server has got connected from %s.\n", inet_ntoa(addr_remote.sin_addr));

		/*Receive File from Client */
		char* fr_name = "/home/aryan/Desktop/receive.txt";
		FILE *fr = fopen(fr_name, "a");
		if(fr == NULL)
			printf("File %s Cannot be opened file on server.\n", fr_name);
		else
		{
			bzero(revbuf, LENGTH); 
			int fr_block_sz = 0;
			while((fr_block_sz = recv(nsockfd, revbuf, LENGTH, 0)) > 0) 
			{
			    int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
				if(write_sz < fr_block_sz)
			    {
			        error("File write failed on server.\n");
			    }
				bzero(revbuf, LENGTH);
				if (fr_block_sz == 0 || fr_block_sz != 512) 
				{
					break;
				}
			}
			if(fr_block_sz < 0)
		    {
		        if (errno == EAGAIN)
	        	{
	                printf("recv() timed out.\n");
	            }
	            else
	            {
	                fprintf(stderr, "recv() failed due to errno = %d\n", errno);
					exit(1);
	            }
        	}
			printf("Ok received from client!\n");
			fclose(fr); 
		}

		/* Call the Script */
		system("cd ; chmod +x script.sh ; ./script.sh");

		/* Send File to Client */
		//if(!fork())
		//{
		    char* fs_name = "/home/aryan/Desktop/output.txt";
		    char sdbuf[LENGTH]; // Send buffer
		    printf("[Server] Sending %s to the Client...", fs_name);
		    FILE *fs = fopen(fs_name, "r");
		    if(fs == NULL)
		    {
		        fprintf(stderr, "ERROR: File %s not found on server. (errno = %d)\n", fs_name, errno);
				exit(1);
		    }

		    bzero(sdbuf, LENGTH); 
		    int fs_block_sz; 
		    while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs))>0)
		    {
		        if(send(nsockfd, sdbuf, fs_block_sz, 0) < 0)
		        {
		            fprintf(stderr, "ERROR: Failed to send file %s. (errno = %d)\n", fs_name, errno);
		            exit(1);
		        }
		        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);
		//}
	}
}
Thank you for helping me!
 
Old 07-07-2015, 02:01 AM   #12
tanmoy_sil
LQ Newbie
 
Registered: Jul 2015
Posts: 2

Rep: Reputation: Disabled
help needed

can you please post the script you are using. i really need this program urgently.
 
Old 07-07-2015, 01:40 PM   #13
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
What "script" do you mean?
 
Old 07-07-2015, 01:43 PM   #14
tanmoy_sil
LQ Newbie
 
Registered: Jul 2015
Posts: 2

Rep: Reputation: Disabled
help needed

the script that you mentioned as script.sh. i need this program for interfacing an ARM9 cpu for data acquisition. can you please tell me of what should i do if i need to send a data file stored in the CPU when asked by the client. I really need this help. I am not from CS background and have a big problem in understanding c programs.
 
Old 07-07-2015, 01:46 PM   #15
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,263
Blog Entries: 24

Rep: Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194
@tanmoy_sil - This thread has been dead for 3+ years, so better to open your own thread with your own question describing what you actually need. Asking for code without any description of what you actually mean is very vague to say the least, and only clutters the forum and search results.

Ah! We cross posted, I see you provided some detail. Still, if you could start your own thread with your own specific requirements you would get better results.

And welcome to LQ!

Last edited by astrogeek; 07-07-2015 at 01:49 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Client TCP socket recv returning 0 when server closes the connection dfbloemen Programming 3 06-21-2012 09:24 AM
Client Server Socket TCP/IP program in C Linux over HTTPS fahad.anwar Linux - Newbie 6 05-29-2012 03:59 AM
Client Server Socket TCP/IP program in C Linux using threads fahad.anwar Linux - Newbie 2 05-18-2012 04:34 AM
[SOLVED] How could server detect closed client socket using TCP and c++? Lobinho Programming 6 08-10-2010 02:28 PM
Problem to transfer binary file over TCP socket yhus Linux - Networking 3 02-28-2006 08:41 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:22 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration