Reputation: 3862
I am trying to upload a file to my ftp server using sockets. It connects to the server and can read the directories but doesn't upload the file. "STOR" command creates a file in the server with an empty content. Why I am getting "No data connection" response from server and my file is empty?
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
argv[0]="2";
argv[1]="ip";
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
char mesUser[100]="USER ftpuser\n";
char mesPass[100]="PASS pass\n";
char meStor[100]="STOR xx\n";
char mesPasv[100]="PASV\n";
char meAppe[100]="APPE xx\n";
argc=2;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(21);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
//serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
if( send(sockfd , mesUser , strlen(mesUser) , 0) < 0)
{
perror("send failed");
return 1;
}
if( send(sockfd , mesPass , strlen(mesPass) , 0) < 0)
{
perror("send failed");
return 1;
}
char* fr_name = "pic.jpg";
FILE *fr = fopen(fr_name, "r");
if(fr == NULL){
printf("File cannot be opened");
return 0;
}
else{
/*if( send(sockfd , mesPasv , strlen(mesPasv) , 0) < 0)
{
perror("send failed");
return 1;
}*/
if( send(sockfd , meStor , strlen(meStor) , 0) < 0)
{
perror("send failed");
return 1;
}
char buffer[100];
fscanf(fr,"%s",buffer);
write(sockfd,buffer,100);
if( send(sockfd , meAppe , strlen(meAppe) , 0) < 0)
{
perror("send failed");
return 1;
}
//close(sockfd);
}
/*if( send(sockfd , meStor , strlen(meStor) , 0) < 0)
{
perror("send failed");
return 1;
}
*/
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
return 0;
}
}
if(n < 0)
{
printf("\n Read error \n");
return 0;
}
return 0;
}
Output:
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 6 of 50 allowed.
220-Local time is now 14:41. Server port: 21.
220 You will be disconnected after 15 minutes of inactivity.
331 User username OK. Password required
230 OK. Current restricted directory is /
425 No data connection
425 No data connection
Upvotes: 1
Views: 20969
Reputation: 2590
i hope this will be useful to you :
int receiveFile(int socket, char text[]) {
FILE *fp;
int nsize,k, i, size=0, temp_size, mul = 1, numbytes, lala, recvd;
int count_freq, repeat;
char ch,buf[20],file_buf[505], temp_buf[505];
saferead(socket, text,80);
if(text[0] == '/')
return 1;
nsize = strlen(text);
char name[nsize];
strncpy(name, text, nsize-1);
name[nsize-1] = '\0';
if ((fp = fopen(name,"w")) == NULL) {
perror(" Can't open file");
return 1;
}
if ((numbytes=recv(socket, buf, 10, 0)) == -1) {
perror("Cant receive size of the file....\n\n");
return 1;
}
for( i=0; i<=9; i++ ){
size = size + ( buf[i]*mul );
mul = mul * 10;
}
recvd = 0;
printf("Received File: %s\n", name);
repeat = size/MAXDATASIZE;
if ( repeat>50 )
count_freq = repeat/50;
i=0;
while( recvd < size ){
if ((numbytes=recv(socket, temp_buf, MAXDATASIZE, 0)) == -1) {
perror("Error receiving file from server....\n\n");
return 1;
}
fwrite( temp_buf, sizeof(temp_buf[0]), numbytes, fp );
recvd = recvd + numbytes;
}
fclose(fp);
}
int sendFile(int socket, char text[]) {
FILE *fp;
int size =0, k, status, nsize = 0, temp_size, i, sent, numbytes, lala;
char buf[20], file_buf[505], temp_buf[505];
char ch;
struct stat info;
nsize = strlen(text);
char name[nsize];
lala = strlen(name);
strncpy(name, text, nsize-1);
name[nsize-1] = '\0';
lala = strlen(name);
if((fp = fopen(name, "r")) == NULL) {
perror("Can't open file");
text[0] = '/';
write(socket,text, 80);
return 1;
}
write(socket,text, 80);
printf("Sending File: %s\n",text);
status = stat( name,&info );
if( status == -1 ){
printf(" fstat failed \n");
return 1;
}
size = info.st_size;
temp_size = size;
for( i=0; i<=9; i++ ) {
buf[i] = size%10;
size = size/10;
}
if (send(socket, buf, 10, 0) == -1){
perror("Cant send file size...\n\n");
return 1;
}
i = 0;
sent = 0;
while( sent <= temp_size ){
ch = fgetc(fp);
if( sent == temp_size ){
if (i>0){
if (( numbytes = send(socket, file_buf, i, 0)) == -1)
perror("Error in sending file.....\n\n\n");
}
break;
}
file_buf[i++] = ch;
if(i == MAX_BUFSIZE){
if (( numbytes = send(socket, file_buf, MAX_BUFSIZE, 0)) == -1)
perror("Error in sending file....\n\n\n");
i = 0;
}
sent++;
}
fclose(fp);
}
Upvotes: 0
Reputation: 3369
It looks like you have an incomplete understanding of the FTP protocol. FTP works on the idea of having 2 socket connections between the client and the server. The first is a "control" connection, and the second is a "data" connection. On the control connection, text commands are sent back and forth, as you are doing in your code. When data needs to be sent back and forth, it is done using the data connection.
There are two ways for FTP to set up a data connection, described here:
In brief, you'll need to:
PASV
command.scanf
).It's been a while since I last wrote with sockets in C, and I don't have the time to write an example, but this should be enough to get you started. (Here is the specification for FTP. RFC's like this are heavy reading, but they are unambiguous and can answer a lot of questions, if you can learn to read them.)
Upvotes: 11