LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
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-22-2009, 08:14 AM   #1
htabesh
LQ Newbie
 
Registered: May 2006
Location: Iran-Tehran
Distribution: Enterprise RedHat
Posts: 25

Rep: Reputation: 16
Question Socket Programming Send File


Hi my friends;
this is my client and server. I can receive text file. but I can't send other type of file like PDF,Docx,Odt and ...
what's the problem?

Server:
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main ( int agrc, char *argv[] )
{
	/******** Program Variable Define & Initialize **********/        
	int Main_Socket; 	// Main Socket For Server
	int Communication_Socket; // Socket For Special Clients
	int Status; // Status Of Fucntion	
	struct sockaddr_in Server_Address; // Address Of Server
	struct sockaddr_in Client_Address; // Address Of Client That Communicate Whit Server
	int Port ;
        char Buff[100] = "";
	Port = atoi(argv[2]);
	printf ("Server Communicating By Using Port %d\n", Port);
	/******** Create A Socket To Communicate With Server **********/
	Main_Socket = socket ( AF_INET, SOCK_STREAM, 0 );
	if ( Main_Socket == -1 )
	{
		printf ("Sorry System Can Not Create Socket!\n");
	}
	/******** Create A Address For Server To Communicate **********/
	Server_Address.sin_family = AF_INET;
	Server_Address.sin_port = htons(Port);
	Server_Address.sin_addr.s_addr = inet_addr(argv[1]);
	/******** Bind Address To Socket **********/
	Status = bind ( Main_Socket, (struct sockaddr*)&Server_Address, sizeof(Server_Address) );
	if ( Status == -1 )
	{
		printf ("Sorry System Can Not Bind Address to The Socket!\n");
	}
	/******** Listen To The Port to Any Connection **********/
	listen (Main_Socket,12);
	/******** Waiting For Connection **********/
	socklen_t Lenght = sizeof (Client_Address);        
        while (1)
        {            
            Communication_Socket = accept ( Main_Socket, (struct sockaddr*)&Client_Address, &Lenght );            
            if (!fork())
            {
                FILE *fp=fopen("sample","w");
                while(1)
                {
                    char Buffer[2]="";
                    if (recv(Communication_Socket, Buffer, sizeof(Buffer), 0))
                    {
                        if ( strcmp (Buffer,"Hi") == 0  )
                        {
                            break;
                        }
                        else
                        {                            
                            fputs(Buffer,fp);
                        }
                    }
                }
                send(Communication_Socket, "ACK" ,3,0);
                printf("ACK Send");
		exit(0);
            }        
        }
	return 0;
}
Client:
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main ( int agrc, char *argv[] )
{
	int Socket;
	struct sockaddr_in Server_Address;	
	Socket = socket ( AF_INET, SOCK_STREAM, 0 );
	if ( Socket == -1 )
	{	
		printf ("Can Not Create A Socket!");	
	}
	int Port ;
	Port = atoi(argv[2]);	
	Server_Address.sin_family = AF_INET;
	Server_Address.sin_port = htons ( Port );
	Server_Address.sin_addr.s_addr = inet_addr(argv[1]);
	if ( Server_Address.sin_addr.s_addr == INADDR_NONE )
	{
		printf ( "Bad Address!" );
	}	
	connect ( Socket, (struct sockaddr *)&Server_Address, sizeof (Server_Address) );
        FILE *in = fopen("Scan","r");
        char Buffer[2] = "";
        int len;        
        while ((len = fread(Buffer,sizeof(Buffer),1, in)) > 0)
        {            
            send(Socket,Buffer,sizeof(Buffer),0);            
        }
        send(Socket,"Hi",sizeof(Buffer),0);

        char Buf[BUFSIZ];
	recv(Socket, Buf, BUFSIZ, 0);
	//printf("%s\n",Buf);
        if ( strcmp (Buf,"ACK") == 0  )
        {
            printf("Recive ACK\n");
        }        
        close (Socket);
        fclose(in);
	return 0;	
}
 
Old 06-22-2009, 10:24 AM   #2
David1357
Senior Member
 
Registered: Aug 2007
Location: South Carolina, U.S.A.
Distribution: Ubuntu, Fedora Core, Red Hat, SUSE, Gentoo, DSL, coLinux, uClinux
Posts: 1,302
Blog Entries: 1

Rep: Reputation: 107Reputation: 107
Quote:
Originally Posted by htabesh View Post
I can receive text file. But I can't send other types of files. What's the problem?
Your code has several problems. I pointed them out using comments inline below.

Quote:
Originally Posted by htabesh View Post
Server:
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main ( int agrc, char *argv[] )
{
	/******** Program Variable Define & Initialize **********/        
	int Main_Socket; 	// Main Socket For Server
	int Communication_Socket; // Socket For Special Clients
	int Status; // Status Of Fucntion	
	struct sockaddr_in Server_Address; // Address Of Server
	struct sockaddr_in Client_Address; // Address Of Client That Communicate Whit Server
	int Port ;
        char Buff[100] = "";
	Port = atoi(argv[2]);
	printf ("Server Communicating By Using Port %d\n", Port);
	/******** Create A Socket To Communicate With Server **********/
	Main_Socket = socket ( AF_INET, SOCK_STREAM, 0 );
	if ( Main_Socket == -1 )
	{
		printf ("Sorry System Can Not Create Socket!\n");
	}
	/******** Create A Address For Server To Communicate **********/
	Server_Address.sin_family = AF_INET;
	Server_Address.sin_port = htons(Port);
	Server_Address.sin_addr.s_addr = inet_addr(argv[1]);
	/******** Bind Address To Socket **********/
	Status = bind ( Main_Socket, (struct sockaddr*)&Server_Address, sizeof(Server_Address) );
	if ( Status == -1 )
	{
		printf ("Sorry System Can Not Bind Address to The Socket!\n");
	}
	/******** Listen To The Port to Any Connection **********/
        //------------------------------------------------------
        // listen can fail.  You need to check the return value.
        //------------------------------------------------------
	listen (Main_Socket,12);
	/******** Waiting For Connection **********/
	socklen_t Lenght = sizeof (Client_Address);        
        while (1)
        {
            //------------------------------------------------------
            // accept can fail.  You need to check the return value.
            //------------------------------------------------------
            Communication_Socket = accept ( Main_Socket, (struct sockaddr*)&Client_Address, &Lenght );            
            if (!fork())
            {
                //-----------------------------------------------------
                // fopen can fail.  You need to check the return value.
                //-----------------------------------------------------
                FILE *fp=fopen("sample","w");
                while(1)
                {
                    char Buffer[2]="";
                    //-----------------------------------------------
                    // You need to check the return value here.
                    // recv can return -1, which qualifies as true
                    // according to the rules for truth in C.
                    //-----------------------------------------------
                    if (recv(Communication_Socket, Buffer, sizeof(Buffer), 0))
                    {
                        //--------------------------------------------
                        // You are using strcmp on a buffer that will
                        // not be NULL terminated.  Either use memcmp,
                        // or change the buffer length above to 3.
                        //--------------------------------------------
                        if ( strcmp (Buffer,"Hi") == 0  )
                        {
                            break;
                        }
                        else
                        {   
                            //----------------------------------------
                            // This needs to be an fwrite.  fputs                           
                            // stops when it reaches a '\0' character.
                            // Binary files are filled with '\0'
                            // characters, so data will be lost.
                            //----------------------------------------
                            fputs(Buffer,fp);
                        }
                    }
                }
                //----------------------------------------------------
                // send can fail.  You need to check the return value.
                //----------------------------------------------------
                send(Communication_Socket, "ACK" ,3,0);
                printf("ACK Send");
		exit(0);
            }        
        }
	return 0;
}

Last edited by David1357; 06-22-2009 at 12:19 PM. Reason: Fix erroneous statement about the behaviour of fputs.
 
Old 06-22-2009, 11:33 AM   #3
htabesh
LQ Newbie
 
Registered: May 2006
Location: Iran-Tehran
Distribution: Enterprise RedHat
Posts: 25

Original Poster
Rep: Reputation: 16
Thanks, but my Client can send text and plain text. How can I Send for example PDF file?
 
Old 06-22-2009, 12:18 PM   #4
David1357
Senior Member
 
Registered: Aug 2007
Location: South Carolina, U.S.A.
Distribution: Ubuntu, Fedora Core, Red Hat, SUSE, Gentoo, DSL, coLinux, uClinux
Posts: 1,302
Blog Entries: 1

Rep: Reputation: 107Reputation: 107
Quote:
Originally Posted by htabesh View Post
Thanks, but my Client can send text and plain text. How can I Send for example PDF file?
I already told you: Use fwrite instead of fputs.

fputs will write until it finds a '\0' character. Binary files are filled with those, so it will not write all the data.
 
Old 06-22-2009, 03:46 PM   #5
htabesh
LQ Newbie
 
Registered: May 2006
Location: Iran-Tehran
Distribution: Enterprise RedHat
Posts: 25

Original Poster
Rep: Reputation: 16
Thanks. I want to Send file name before sending file. I try this:

Client:
Code:
char *path;
char *filename;
path = "/var/www/index.html";
filename = strrchr(path, '/') + 1;
send(Socket,filename,sizeof(filename),0);
But I have a problem in my server code. Server don't know size of filename!
I need absolute size of Buffer (filename)!

Server:
Code:
char Buffer[?];
recv(Communication_Socket, Buffer, sizeof(Buffer), 0);
is there any way to define a fit and flexible Buffer (fit and flexible size), independent of Client?

Last edited by htabesh; 06-22-2009 at 03:48 PM.
 
Old 06-22-2009, 05:10 PM   #6
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
you don't need to know the size.
recv reads size bytes into the buffer.
if it's not big enough you go round again in a loop.
you can use realloc to make a flexible buffer.
read the man pages.

what are you doing with the data?
do you need to save it all?
 
Old 06-22-2009, 05:32 PM   #7
David1357
Senior Member
 
Registered: Aug 2007
Location: South Carolina, U.S.A.
Distribution: Ubuntu, Fedora Core, Red Hat, SUSE, Gentoo, DSL, coLinux, uClinux
Posts: 1,302
Blog Entries: 1

Rep: Reputation: 107Reputation: 107
Quote:
Originally Posted by htabesh View Post
Is there any way to define a fit and flexible buffer independent of client?
You can use some structures like this:

Code:
typedef struct _MESSAGE_HEADER
{
    int    iType;
    int    iSize;
} MESSAGE_HEADER, *PMESSAGE_HEADER;

typedef char MESSAGE_PAYLOAD[1024];

typedef struct _MESSAGE
{
    MESSAGE_HEADER    Header;
    MESSAGE_PAYLOAD   Data;
} MESSAGE, *PMESSAGE;
Then you can declare a message on the stack like this:
Code:
int bogus(void)
{
    MESSAGE Message;

    Message.Header.iType = 1;
    Message.Header.iSize = sizeof(Message);
    strcpy(Message.Data, "FileName.txt");
    // Send your message somewhere
}
As long as your server and client use the same definitions for all the structures, everything will work. You can use the "iType" and "iSize" fields to determine whether or not the received data is a file name message or a data message.
 
Old 06-23-2009, 12:26 AM   #8
htabesh
LQ Newbie
 
Registered: May 2006
Location: Iran-Tehran
Distribution: Enterprise RedHat
Posts: 25

Original Poster
Rep: Reputation: 16
See this:

Client:

Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main ( int agrc, char *argv[] )
{
	int Socket;
	struct sockaddr_in Server_Address;	
	Socket = socket ( AF_INET, SOCK_STREAM, 0 );
	if ( Socket == -1 )
	{	
		printf ("Can Not Create A Socket!");	
	}
	int Port ;
	Port = atoi(argv[2]);	
	Server_Address.sin_family = AF_INET;
	Server_Address.sin_port = htons ( Port );
	Server_Address.sin_addr.s_addr = inet_addr(argv[1]);
	if ( Server_Address.sin_addr.s_addr == INADDR_NONE )
	{
		printf ( "Bad Address!" );
	}	
	connect ( Socket, (struct sockaddr *)&Server_Address, sizeof (Server_Address) );


        char *path;
        char *filename;
        path = "/home/hosein/Desktop/Project-30-3/Scan.pdf";
        filename = strrchr(path, '/') + 1;
        send(Socket,filename,sizeof(filename),0);

        FILE *in = fopen("1.tar.gz","r");
        char Buffer[2] = "";
        int len;
        while ((len = fread(Buffer,sizeof(Buffer),1, in)) > 0)
        {            
            send(Socket,Buffer,sizeof(Buffer),0);            
        }
        send(Socket,"Hi",sizeof(Buffer),0);

        char Buf[BUFSIZ];
	recv(Socket, Buf, BUFSIZ, 0);
        if ( strcmp (Buf,"ACK") == 0  )
        {
            printf("Recive ACK\n");
        }        
        close (Socket);
        fclose(in);
	return 0;	
}
Server:

Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main ( int agrc, char *argv[] )
{
	/******** Program Variable Define & Initialize **********/
	int Main_Socket; 	// Main Socket For Server
	int Communication_Socket; // Socket For Special Clients
	int Status; // Status Of Fucntion
	struct sockaddr_in Server_Address; // Address Of Server
	struct sockaddr_in Client_Address; // Address Of Client That Communicate Whit Server
	int Port ;
        char Buff[100] = "";
	Port = atoi(argv[2]);
	printf ("Server Communicating By Using Port %d\n", Port);
	/******** Create A Socket To Communicate With Server **********/
	Main_Socket = socket ( AF_INET, SOCK_STREAM, 0 );
	if ( Main_Socket == -1 )
	{
		printf ("Sorry System Can Not Create Socket!\n");
	}
	/******** Create A Address For Server To Communicate **********/
	Server_Address.sin_family = AF_INET;
	Server_Address.sin_port = htons(Port);
	Server_Address.sin_addr.s_addr = inet_addr(argv[1]);
	/******** Bind Address To Socket **********/
	Status = bind ( Main_Socket, (struct sockaddr*)&Server_Address, sizeof(Server_Address) );
	if ( Status == -1 )
	{
		printf ("Sorry System Can Not Bind Address to The Socket!\n");
	}
	/******** Listen To The Port to Any Connection **********/        
	listen (Main_Socket,12);	
	socklen_t Lenght = sizeof (Client_Address);
        while (1)
        {
            Communication_Socket = accept ( Main_Socket, (struct sockaddr*)&Client_Address, &Lenght );
            if (!fork())
            {

                char CH[4];
                recv(Communication_Socket, CH, sizeof(CH), 0);
                printf("%s\n",CH);
                
                FILE *fp=fopen("sample.tar.gz","w");
                while(1)
                {
                    char Buffer[2]="";
                    if (recv(Communication_Socket, Buffer, sizeof(Buffer), 0))
                    {
                        if ( strcmp (Buffer,"Hi") == 0  )
                        {
                            break;
                        }
                        else
                        {
                            fwrite(Buffer,sizeof(Buffer),1, fp);
                        }
                    }
                }
                fclose(fp);
                send(Communication_Socket, "ACK" ,3,0);
                printf("ACK Send");
		exit(0);
            }
        }
	return 0;
}
for example if I declare CH[100], there will be problem to receive file.
whit CH[8] everything work right.

Last edited by htabesh; 06-23-2009 at 12:29 AM.
 
Old 06-23-2009, 05:28 AM   #9
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
See this:

Client:
Code:
tar cvf - file | nc localhost 50123
Server:
Code:
nc -l 50123 | tar xvf -
 
Old 06-23-2009, 07:36 AM   #10
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
This code is wrong:
Code:
...
        send(Socket,filename,sizeof(filename),0);
...
Do not use the sizeof()... use the strlen(). The sizeof() will yield 4-bytes, which is the size of the pointer. You want the length of the filename.
 
Old 06-23-2009, 10:08 AM   #11
htabesh
LQ Newbie
 
Registered: May 2006
Location: Iran-Tehran
Distribution: Enterprise RedHat
Posts: 25

Original Poster
Rep: Reputation: 16
I use strlen() instead of sizeof(). But my problem don't solved!
 
Old 06-23-2009, 12:52 PM   #12
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
I'm sorry that your problem was not solved. From what I understand, you are attempting to send a string (e.g. a filename) from a client to a server, and then afterwards the client will send the file's data content.

Here's a synopsis of what the server COULD look like:
Code:
void handleClient(const int sd);

int main(int argc, char** argv)
{
   int listen_sd = socket(AF_INET, SOCK_STREAM, 0);

   // ...

   bind(listen_sd, (struct sockaddr*) &addr, sizeof(addr));

   listen(listen_sd, 5);

   for (;;)
   {
      int client_sd = accept(listen_sd, 0, 0);

      if (client_sd > 0 && fork() == 0)
      {
         handleClient(client_sd);
         exit(0);
      }
   }

   close(listen_sd);
}

void handleClient(const int sd)
{
   fd_set savefds;
   FD_ZERO(&savefds);
   FD_SET(sd, &savefds);

   enum State { WAITING_FOR_FILENAME, WAITING_FOR_DATA };

   State state = WAITING_FOR_FILENAME;
   FILE* file  = 0;
   int   done  = 0;

   while (!done)
   {
      fd_set readfds = savefds;
      int    sel = select(sd, &readfds, 0, 0, 0);

      if (sel <= 0)
      {
         done = 1;
         continue;
      }

      char buf[1024] = {0};

      int rtn = read(sd, buf, sizeof(buf), 0);

      if (rtn <= 0)
      {
         if (file)
         {
            fflush(file);
            fclose(file);
         }
         done = 1;
         continue;
      }

      if (state == WAITING_FOR_FILENAME)
      {
         file = fopen(buf, "w+");

         if (file)
         {
            state = WAITING_FOR_DATA;
         }
         else
         {
            fprintf(stderr, "Cannot open file %s\n", buf);
            done = 1;
         }
      }
      else   // WAITING_FOR_DATA
      {
         fwrite(buf, rtn, 1, file);
      }
   }

   close(sd);
}
Sorry for the lack of comments; I hope it is clear what is going on. Also, I did not compile/test this, so forgive me if there is a minor issue.

As for the client, something like:
Code:
int main(int argc, char** argv)
{
   int sd = socket(AF_INET, SOCK_STREAM, 0);

   // ...

   int rtn = connect(sd, (struct sockaddr*) &addr, sizeof(addr));

   if (rtn != 0)
   {
      perror("Failed to connect to the server.");
      return 1;
   }

   const char* filename = "Foo.txt";

   if (send(sd, filename, strlen(filename), 0) == strlen(filename))
   {
      FILE* file = fopen(filename, "r");

      if (file)
      {
         char buf[1024] = {0};
         int  bytes     = 0;

         while ((bytes = fread(buf, sizeof(buf), 1, file)) > 0)
         {
            send(sd, buf, bytes, 0);
         }
      }
   }

}
Once again, I have not tested this code, but it is logically laid out to perform the task you require.

You may want to consider having the client/server perform some sort of hand-shaking, so that ACK/NAK messages can be sent from the server to the client to indicate success/failure with the request; you never know, the server may encounter an error.

Last edited by dwhitney67; 06-23-2009 at 12:58 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
send text file over socket tqa Programming 1 11-22-2008 04:37 PM
how to send custom frame in socket programming rahb20 Programming 4 10-24-2008 09:56 PM
Socket Programming: SMTP program to send email through Unix WinX187 Programming 1 05-12-2007 06:35 AM
Send a file over a connected socket? JohnDaVinci Programming 5 09-15-2006 08:58 PM

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

All times are GMT -5. The time now is 07:51 AM.

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