Tuesday, 15 September 2015

C - TCP File transfer -



C - TCP File transfer -

i trying file transfer on tcp through server-client relationship. having problem every time server receives client's requested file prints out requested file name garbage @ end, , continues on produce segmentation fault. whenever info client, text document manages somehow incorporated part of title. have pasted code below server , client

server.c

/*code server portion of server-client setup*/ /*communication occurs overs tcp*/ #include <stdio.h> /* printf() , fprintf() */ #include <sys/socket.h> /* socket(), bind(), , connect() */ #include <arpa/inet.h> /* sockaddr_in , inet_ntoa() */ #include <stdlib.h> /* atoi() , exit() */ #include <string.h> /* memset() */ #include <unistd.h> /* close() */ #include <errno.h> /* error numbers */ #include <dirent.h> /* directories */ #define maxpending 5 /* maximum outstanding connection requests */ #define maxlen 255 /* longest string */ void diewitherror(char *errormessage); /* error handling function */ int main(int argc, char *argv[]) { int servsock; /* socket descriptor server */ int clntsock; /* socket descriptor client */ struct sockaddr_in echoservaddr; /* local address */ struct sockaddr_in echoclntaddr; /* client address */ unsigned short echoservport; /* server port */ unsigned int clientoption, clntlen; /* length of client address info construction */ char data_recv[maxlen+1]; /* info received client */ int recvmsgsize; /* size of message received */ char data_sent[2000]; /* info sent client */ char file_request[50]; /* file requested client */ char file[2000]; /* lastly file sent client */ socklen_t len; if (argc != 2) /* test right number of arguments */ { fprintf(stderr, "usage: %s <server port>\n", argv[0]); exit(1); } echoservport = atoi(argv[1]); /* first arg: local port */ /* create socket incoming connections */ if ((servsock = socket(pf_inet, sock_stream, ipproto_tcp)) < 0) diewitherror("socket() failed"); /* build local address construction */ memset(&echoservaddr, 0, sizeof(echoservaddr)); /* 0 out construction */ echoservaddr.sin_family = af_inet; /* net address family */ echoservaddr.sin_addr.s_addr = htonl(inaddr_any); /* incoming interface */ echoservaddr.sin_port = htons(echoservport); /* local port */ /* bind local address */ if (bind(servsock, (struct sockaddr *) &echoservaddr, sizeof(echoservaddr)) < 0) diewitherror("bind() failed"); /* mark socket hear incoming connections */ if (listen(servsock, maxpending) < 0) diewitherror("listen() failed"); /* wait client connect */ if ((clntsock = accept(servsock, (struct sockaddr *) &echoclntaddr, &clntlen)) < 0) diewitherror("accept() failed"); /* run forever */ while(atoi(data_recv) != -1){ /* block until receive message client */ if(recvmsgsize = recv(clntsock, data_recv, sizeof(data_recv), 0) < 0) { printf("could not block socket. failed : %s\n", strerror(errno)); } printf("handling client %s\n", inet_ntoa(echoclntaddr.sin_addr)); printf("%d\n", atoi(data_recv)); recvmsgsize = 1000; printf("%d\n", atoi(data_recv)); char temp[255]; switch(atoi(data_recv)){ printf("%d\n", atoi(data_recv)); case 1: printf("client has requested list of files\n"); dir * d; struct dirent * dp; d = opendir("."); if(d != null){ while((dp = readdir(d)) != null){ if(dp->d_type == dt_reg){ strcat(temp, dp->d_name); strcat(temp, "\n"); } } strcpy(data_recv, temp); strcpy(temp, ""); if(send(clntsock, data_recv, recvmsgsize, 0) < 0){ printf("send() sent different number of bytes expected"); } closedir(d); } break; case 2: printf("client has requested single file. waiting file name.\n"); /* block until receive message client */ if(recvmsgsize = recv(clntsock, file_request, sizeof(file_request), 0) < 0) { printf("could not block socket\n"); printf("failed next error: %s\n", strerror(errno)); } printf("client has request: %s\n", file_request); file *fp; fp = fopen(file_request, "r"); if(fp == null) { // send message client file not exist printf("specified file not exist."); } fseek(fp, 0, seek_end); size_t file_size = ftell(fp); fseek(fp, 0, seek_set); if(fread(file, file_size, 1, fp) <= 0) { // send message unable re-create file buffer printf("unable re-create file buffer"); exit(1); } if (send(clntsock, file, sizeof(file), 0) < 0) { printf("error in sending file"); } bzero(file, sizeof(file)); break; case 3: break; case 4: printf("client has closed connection. waiting on new clients"); break; } recvmsgsize = 0; data_recv[0] = 0; } close(servsock); }

client.c

/*code client portion of server-client setup*/ /*communication occurs overs tcp*/ #include <stdio.h> /* printf() , fprintf() */ #include <sys/socket.h> /* socket(), connect(), sendto(), , recvfrom() */ #include <arpa/inet.h> /* sockaddr_in , inet_addr() */ #include <stdlib.h> /* atoi() , exit() */ #include <string.h> /* memset() */ #include <unistd.h> /* close() */ #include <stdbool.h> /* boolean values */ #define rcvbufsize 255 /* size of receive buffer */ void diewitherror(char *errormessage); /* error handling function */ char * printmenu(); int main(int argc, char *argv[]) { int sock,i,num; /* socket descriptor */ struct sockaddr_in echoservaddr; /* echo server address */ struct sockaddr_in fromaddr; /* address of info sender */ unsigned short echoservport; /* echo server port */ char *servip; /* server ip address (dotted quad) */ char *echostring; /* string send echo server */ char echobuffer[rcvbufsize]; /* buffer echo string */ unsigned int echostringlen; /* length of string echo */ int bytesrcvd, totalbytesrcvd; /* bytes read in single recv() , total bytes read */ char menuoption[1]; /* user menu seclection send server */ char buffer[rcvbufsize+1]; /* buffer receiving info server */ int recvdatalen; /* length of received response */ char * menumsg; /* used print menu options */ char * temp[255] = {0}; char file_buffer[2000]; /* file sent server */ char file_request[50]; /* file requested client */ if (argc != 3) /* test right number of arguments */ { fprintf(stderr,"usage: %s <server ip> [<port id>]\n", argv[0]); exit(1); } servip = argv[1]; /* first arg: server ip address (dotted quad) */ if (argc == 3) { echoservport = atoi(argv[2]); /* utilize given port, if */ } else { fprintf(stderr,"usage: %s requires [<port id>]\n", argv[0]); } /* create reliable, stream socket using tcp */ if ((sock = socket(pf_inet, sock_stream, ipproto_tcp)) < 0) diewitherror("socket() failed"); /* build server address construction */ memset(&echoservaddr, 0, sizeof(echoservaddr)); /* 0 out construction */ echoservaddr.sin_family = af_inet; /* net address family */ echoservaddr.sin_addr.s_addr = inet_addr(servip); /* server ip address */ echoservaddr.sin_port = htons(echoservport); /* server port */ /* found connection echo server */ if (connect(sock, (struct sockaddr *) &echoservaddr, sizeof(echoservaddr)) < 0) diewitherror("connect() failed"); //echostringlen = strlen(echostring); /* determine input length */ menumsg = printmenu(); while(atoi(menuoption) != -1){ printf("%s", menumsg); scanf("%s", &menuoption[0]); switch(atoi(menuoption)){ case 1: /* send menu selection server indicating client wants list of files on server */ if (send(sock, menuoption, sizeof(menuoption), 0) < 0){ printf("sendto() sent different number of bytes expected"); } printf("\nyou take recieve list of files server\n\n"); printf("below returned response server:\n"); /* receive response server */ if ((bytesrcvd = recv(sock, buffer, rcvbufsize - 1, 0)) <= 0) diewitherror("recv() failed or connection closed prematurely"); /* null terminate received info */ buffer[bytesrcvd] = '\0'; printf("%s\n", buffer); /* print echoed arg */ break; case 2: /* send menu selection server indicating client wants list of files on server */ if (send(sock, menuoption, sizeof(menuoption), 0) < 0){ printf("sendto() sent different number of bytes expected"); } printf("you take retrieve single file server\n"); printf("what file like: "); scanf("%s", &file_request[0]); if (send(sock, file_request, strlen(file_request), 0) < 0) { printf("sendto() sent different number of bytes expected"); } /* recv response */ bytesrcvd = sizeof(fromaddr); if (recvdatalen = recv(sock, buffer, sizeof(buffer), 0) < 0) { printf("recvfrom() failed\n"); } char new_file[] = "copied"; strcat(new_file, buffer); file *fp; fp = fopen(new_file, "w+"); if(fwrite(buffer, 1, sizeof(buffer), fp) < 0) { printf("error writting file\n"); exit(1); } break; case 3: printf("you take retrieve files server\n"); break; case 4: /* send menu selection server indicating client wants list of files on server */ if (send(sock, menuoption, sizeof(menuoption), 0) < 0){ printf("sendto() sent different number of bytes expected"); } printf("closing connection\n"); close(sock); exit(0); default: printf("you picked invalid option. seek again.\n"); break; } } printf("\n"); /* print final linefeed */ close(sock); exit(0); } char * printmenu() { static char message[250] = "select alternative below:\n"; strcat(message, "(1) list files on server\n"); strcat(message, "(2) retrieve file server\n"); strcat(message, "(3) retrieve files server\n"); strcat(message, "(4) close connection\n"); strcat(message, "enter selection: "); homecoming message; }

you not sending null terminator server.

if (send(sock, file_request, strlen(file_request), 0) < 0) { printf("sendto() sent different number of bytes expected"); }

strlen not count null terminator length.

replace strlen(file_request) + 1.

i not mean perfect solution, way point mistake.

c tcp

No comments:

Post a Comment