LinuxQuestions.org
Help answer threads with 0 replies.
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 01-02-2015, 10:21 AM   #1
goldriver92
LQ Newbie
 
Registered: Dec 2014
Posts: 21

Rep: Reputation: Disabled
File contents printing with the filename when sending a string from client to server


I am trying to establish a connection between client and server to send a file to the server from a client. I have been successfully able to send files to the server but i am facing a problem with the the filename whenever i try to send any string to the server and use it in naming the filename at the server side, the string is successfully concatenated but it saves the filecontents in the filename. I have been pulling my hair out for this problem but couldn't reach a solution

for example:
i am sending a file hello1.txt to server and the server has to save it as abcxyz.txt as i am sending the "xyz" from the client. BUT Whenever i am doing this ,the file saves as abcxyzfilecontents.txt
If i saved in the .txt file "you123" ,my file at server side would save as abcxyzyou123.txt









Here are my codes:


Know that the server code implements a multi threaded server. The functionality to be discussed is defined in myfunc
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>
# include<pthread.h>
//#define PORT 20000 
#define BACKLOG 5
#define LENGTH 1024 
int f=1;

void error(const char *msg)
{
	perror(msg);
	exit(1);
}
void *myfunc(void *recvsocket);
//void *myfunc2(void *recvsocket2)

int main(int argc, char *argv[])
{
	int sockfd,newsockfd,portno;
	socklen_t clilen;
	char buffer[32];
	struct sockaddr_in serv_addr,cli_addr;
	int n;
      int num1,num2,sum;
char revbuf[LENGTH];
      pthread_t threadid;
	
	if(argc<2)
	{
		fprintf(stderr,"No port number provided\n");
		exit(1);
	}    
	
	sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0)
		error("ERROR opning socket");
	bzero((char *)&serv_addr,sizeof(serv_addr));
	portno=atoi(argv[1]);
	serv_addr.sin_family=AF_INET;
	serv_addr.sin_addr.s_addr=INADDR_ANY;
	serv_addr.sin_port=htons(portno);
	
	
	if(bind(sockfd, (struct sockaddr *)&serv_addr,sizeof(serv_addr))<0)
		error("error on binding");
	listen(sockfd,5);
	clilen=sizeof(cli_addr);
        //int c=80;   
while(1)
{
newsockfd=accept(sockfd,(struct sockaddr *)&cli_addr,&clilen);
int a=pthread_create(&threadid,NULL,myfunc,(void *)newsockfd);

pthread_detach(threadid);
sched_yield();

}
}
void *myfunc(void *recvsocket)
{
int tempsock=(int *)recvsocket;
char revbuf[LENGTH];
char test[1024]={0};
char filename[1024] = "/home/tabk/Desktop/texts/abc";
f=f+1;
bzero(revbuf,1024);
char sockbuf[LENGTH];
int m=read(tempsock,sockbuf,sizeof(sockbuf));

sprintf(test,"%s",revbuf);

strcat(filename,sockbuf);

bzero(revbuf,LENGTH);

sprintf(revbuf,"%ld",f);

strcat(filename,revbuf);

char ext[1024]=".txt";

strcat(filename,ext);

printf("\nourfilename:%s",filename);		

char* fr_name=filename;

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(tempsock, 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 != 1024) 
				{
					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("\nOk received from client!\n");
			fclose(fr); 
		

		    close(tempsock);
		    printf("\n[Server] Connection with Client closed. Server will wait now...\n");
		    while(waitpid(-1, NULL, WNOHANG) > 0);
		//}
	}

}




Client.c:
#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 LENGTH 1024
void error(const char *msg)    
{
	perror(msg);
	exit(0);
}
int main(int argc, char *argv[])
{
	int sockfd,portno,n,s;
	struct sockaddr_in serv_addr;
	struct hostent *server;
	char buffer[32];
        char sdbuf[LENGTH]; 
        int f;
	char revbuf[LENGTH];
	if(argc<3)
	{
		fprintf(stderr,"usage %s hostname port\n",argv[0]);
		exit(0);
	}

	portno=atoi(argv[2]);
	sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0)
		error("ERROR opning socket");
	server=gethostbyname(argv[1]);
	if(server==NULL)
	{
		fprintf(stderr,"ERROR, no such host\n");
		exit(0);
	}
	bzero((char *)&serv_addr,sizeof(serv_addr));
	serv_addr.sin_family=AF_INET;
	bcopy((char *)server->h_addr,(char *)&serv_addr.sin_addr.s_addr,server->h_length);
	serv_addr.sin_port=htons(portno);
	if(connect(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))<0)
		error("Errror Connecting");
/* Send File to Server */
char fr_name[1024];
printf("\nPlease provide path");
scanf("%s",fr_name);
printf("\nclientfilename:%s",fr_name);
strcpy(sdbuf,"abc");
n=write(sockfd,sdbuf,strlen(sdbuf));
if(n<0)
error("Error writing to socket");

char* filename=fr_name;
 
                printf("\n[Client] Sending %s to the Server... ", filename);
		FILE *fs = fopen(filename, "r");
		if(fs == NULL)
		{
			printf("ERROR: File %s not found.\n", filename);
			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", filename, errno);
		        break;
		    }
		    bzero(sdbuf, LENGTH);
		}
		printf("Ok File %s from Client was Sent!\n", filename);
	

		close (sockfd);
	printf("[Client] Connection lost.\n");
	return (0);
}

Result of terminal at server side:
http://imgur.com/90rjv58
At client side:
http://imgur.com/GvkeKNS

Last edited by goldriver92; 01-02-2015 at 05:31 PM.
 
Old 01-02-2015, 11:41 AM   #2
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
If you use the code tags i.e. [code][/code] when posting code it will be much easier to read.

When sending data across a network you need to establish a protocol. The receiving socket has no idea you've made two separate writes. You need to think of a way to delineate your data.
 
1 members found this post helpful.
Old 01-02-2015, 11:42 AM   #3
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,863
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
As a start, edit your post, add [code] and [/code] tags.
 
Old 01-02-2015, 05:32 PM   #4
goldriver92
LQ Newbie
 
Registered: Dec 2014
Posts: 21

Original Poster
Rep: Reputation: Disabled
Please elaborate on the delineating your data part.
 
Old 01-02-2015, 06:08 PM   #5
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
If you read some network protocols you'll notice they provide a means to separate the distinct parts of the protocol. If the protocol is textual it needs to be something that won't appear in the message portion. HTTP headers are separated from each other by a new line and the headers are separated from the body by a new line without any other characters on the line.

An email can have newlines in the body so to signal an end to the body a period is sent on a new line followed by a new line. Since the message could legitimately have a period and newline as it's last line the protocol has a means of handling that as well (sorry, I don't remember what it is at the moment).

So, if you are going to send a filename and file contents you need a means for the receiver to interpret what it is receiving. i.e. The filename will be sent first followed by a newline; then the size of the file will be sent, followed by a new line; then the file contents will be sent.
 
1 members found this post helpful.
Old 01-03-2015, 08:51 AM   #6
goldriver92
LQ Newbie
 
Registered: Dec 2014
Posts: 21

Original Poster
Rep: Reputation: Disabled
Thanks a lot! That was the main issue. The server wasn't knowing where do the file contents start and when to stop naming the file. So i figured out a solution. I sent a random integer and i waited at the client side for that integer before the client starts sending the file. At the server side i sent the integer after i had finished naming the file. Now i have stumbled upon another issue, suppose i have multiple clients connected to the server at a time,and each connected client is assigned a request number for instance 1,2,3,4 etc. I want such a functionality that When server finishes serving client # 1 and it wants to inform all other connected clients that i have finished serving client # 1 and consequently updates them on their request numbers ,for example the client which was assigned req # 2 is allotted req # 1, the client which was assigned req # 3 is re-assigned req # 2 .How do i achieve this?
 
Old 01-03-2015, 09:35 AM   #7
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,863
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
ad1: Sending the length of the filename would be better than sending a random integer...
ad2: In the common client/server architecture clients aren't interested in each other's activities, they only deal with the server. Of course the server mush have connection-specific data-areas to keep track with clients. Also you have to learn about non-blocking mode and functions select/poll.
 
Old 01-03-2015, 10:13 AM   #8
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
Quote:
Originally Posted by goldriver92 View Post
Thanks a lot! That was the main issue. The server wasn't knowing where do the file contents start and when to stop naming the file. So i figured out a solution. I sent a random integer and i waited at the client side for that integer before the client starts sending the file. At the server side i sent the integer after i had finished naming the file. Now i have stumbled upon another issue, suppose i have multiple clients connected to the server at a time,and each connected client is assigned a request number for instance 1,2,3,4 etc. I want such a functionality that When server finishes serving client # 1 and it wants to inform all other connected clients that i have finished serving client # 1 and consequently updates them on their request numbers ,for example the client which was assigned req # 2 is allotted req # 1, the client which was assigned req # 3 is re-assigned req # 2 .How do i achieve this?
It is possible to send what is called out-of-band data. http://www.gnu.org/software/libc/man...Band-Data.html

It's a somewhat more advanced topic.
 
  


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
[SOLVED] search a directory and add file contents when find string j-me Linux - General 3 01-11-2013 08:54 AM
sed -- replacing a string in a file with the contents of another file? CGP314 Linux - Newbie 10 06-17-2010 04:29 PM
find string in filename and use string to create directories daberkow Linux - Newbie 11 05-01-2009 02:12 PM
Ubuntu NFS server, XP client sees shares but not contents ThunderRd Linux - Server 1 12-27-2008 10:39 PM
Sending message from server to client paulwong Linux - Networking 6 07-22-2005 09:55 AM

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

All times are GMT -5. The time now is 08:31 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