Friday, June 25, 2010

c socket programming : file transfer problem

In the attached server.c and client.c code snippets, if I don't use
at the client side, some extra/strange characters appear at the end
of client.txt.

I want to know why?
server.txt is as simple as this :
----file beginning---
---file end---
All I am trying to do here is to transfer server.txt, from server to client.txt
at the client.

server.c :
 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h>   #include <arpa/inet.h> #include <stdio.h>   #define PORT 2080   main() { 	int sock1,sock2, clength; 	sock1 =  socket(AF_INET,SOCK_STREAM,0); 	struct sockaddr_in serv,cli;   	serv.sin_family = AF_INET; 	serv.sin_port = htons(PORT); 	serv.sin_addr.s_addr = inet_addr(""); 	bind(sock1,(struct sockaddr *)&serv, sizeof(serv)); 	listen(sock1,5); 	clength = sizeof(cli); 	int i=0; 	char buf[50]; 	sock2 = accept(sock1,(struct sockaddr *)&cli,&clength); 	printf("\n Client Connected\n"); 	FILE* fp = fopen("server.txt","r"); 	while(!feof(fp)){ 		//bzero(buf,sizeof(buf)); 		fread(buf,sizeof(char),50,fp); 		write(sock2,buf,50); 	} 	write(sock2,"quit1234",50); 	fclose(fp); 	return 0; }   client.c : #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h>   #include <arpa/inet.h> #include <stdio.h>   #define PORT 2080   main() { 	int sock1; 	sock1 =  socket(AF_INET,SOCK_STREAM,0); 	struct sockaddr_in serv;   	serv.sin_port = htons(PORT); 	printf("%x %x\n",PORT,htons(PORT)); 	serv.sin_family = AF_INET; 	serv.sin_addr.s_addr = inet_addr(""); 	printf("client connecting\n"); 	connect(sock1, (struct sockaddr *)&serv,sizeof(serv)); 	char buf[50]; 	FILE* fp = fopen("client.txt","w"); 	while(1){ 		//bzero(buf,sizeof(buf)); 		read(sock1,buf,50); 		if(strcmp(buf,"quit1234")==0) 		{ 			break;	 		} 		fprintf(fp,"%s",buf); 	} 	fclose(fp); }

Ans : 
No there are only 330 chars to read.  However, your server program is writing out 50 byte chunks each time which is why you have the discrepancy.

So your client is reading correctly what is being sent.  At the moment however, because both programs are working in blocks of 50 bytes you are hanging together.  When you apply fixes to your server however you will potentially get problems again if your buffer is not zeroed because it is still using the fprintf without a length (unless you have implemented my earlier suggestions)

To fix the problem fread returns a length indicating how many characters where actually read.  If you use this as the length parameter to your your write then you will get the the correct number of bytes.

        int len = fread(buf,sizeof(char),50,fp);                 write(sock2,buf,len);         }           char *quitStr = "quite1234";         write(sock2,quitStr,strlen(quitStr));

No comments:

Blog Archive