This program is giving a segmentation fault. Can anyone explain why? I tried using gdb. It says, the error is on readFile(). Am i doing something wrong with memcpy? I am trying to transfer a file in bytes from client to server.
Client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#define BUFFERSIZE 1000
#define IPSIZE 20
#define FILESIZE 100
void readFile(char *name, int sock_fd)
{
FILE *fp = fopen(name, "rb");
char *read_buffer, *buffer[BUFFERSIZE];
unsigned long file_len;
int total_size = 0, flag, rem_size;
//Open file
if (!fp)
{
fprintf(stderr, "Unable to open fp %s", name);
return;
}
//Get file length
fseek(fp, 0, SEEK_END);
file_len=ftell(fp);
fseek(fp, 0, SEEK_SET);
//Allocate memory
read_buffer = (char *)malloc(BUFFERSIZE - 23);
if (!buffer)
{
fprintf(stderr, "Memory error!");
fclose(fp);
return;
}
//Read file contents into buffer
total_size = sizeof(name) + file_len;
printf("Total Size: %d",total_size);
if(file_len < 976)
{
fread(read_buffer, sizeof(read_buffer), 1, fp);
memcpy(buffer, &total_size, sizeof(total_size));
memcpy(buffer[sizeof(total_size)], &name, sizeof(name));
memcpy(buffer[sizeof(total_size)+sizeof(name)], read_buffer, sizeof(read_buffer));
flag = write(sock_fd, htonl(buffer), strlen(buffer));
if (flag < 0)
error("ERROR writing to socket");
}
else
{
while(1)
{
fread(read_buffer, sizeof(read_buffer), 1, fp);
memcpy(buffer, &total_size, sizeof(total_size));
memcpy(buffer[sizeof(total_size)], &name, sizeof(name));
memcpy(buffer[sizeof(total_size)+sizeof(name)], read_buffer, sizeof(read_buffer));
flag = write(sock_fd, htonl(buffer), strlen(buffer));
if (flag < 0)
error("ERROR writing to socket");
rem_size = total_size - 1000;
if(rem_size<0)
break;
}
}
fclose(fp);
}
int main(int argc, char **argv)
{
struct sockaddr_in server_addr;
int sockfd, remote_port_no, n;
char remote_ip[IPSIZE], file_name[FILESIZE];
if(argc!=4)
{
fprintf(stderr,"Usage: ftpc <remote-IP> <remote-port> <local-file-to-transfer>");
exit(0);
}
memset(&(remote_ip), '\0', sizeof(remote_ip)+1);
memcpy(remote_ip, argv[1],sizeof(argv[1])+1);
remote_port_no = atoi(argv[2]);
memset(&(file_name), '\0', sizeof(file_name)+1);
memcpy(file_name, argv[3], sizeof(argv[3])+1);
puts(remote_ip);
puts(file_name);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
printf("OK");
if(sockfd<0)
printf("Socket creation ERROR");
else
printf("Socket creation success");
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(remote_port_no);
server_addr.sin_addr.s_addr = inet_addr(remote_ip);
memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
if(connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
printf("Connect ERROR");
else
printf("Connect Success");
readFile(file_name, sockfd);
return 0;
}
Server.c
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#define BUFFERSIZE 1000
#define IPSIZE 20
#define FILESIZE 100
int main(int argc, char **argv)
{
int listen_fd, connect_fd, n, local_port_no, cli_len;
char buffer[BUFFERSIZE];
struct sockaddr_in serv_addr, client_addr;
FILE *fp;
if(argc != 2)
{
fprintf(stderr,"Usage: ftps <local-port>");
exit(0);
}
local_port_no = atoi(argv[1]);
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(local_port_no);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bzero(&(serv_addr.sin_zero), sizeof(serv_addr.sin_zero));
bind(listen_fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
listen(listen_fd, 1);
cli_len = sizeof(client_addr);
connect_fd = accept(listen_fd, (struct sockaddr *) &client_addr, &cli_len);
recv(connect_fd, buffer, sizeof(buffer), 0);
fp = open("temp","wb");
printf("%d",sizeof(buffer));
fwrite(buffer, sizeof(buffer[0]), sizeof(buffer)/sizeof(buffer[0]), fp);
close(connect_fd);
}
UPDATE
(gdb) list
55 memcpy(buffer[sizeof(total_size)], &name, sizeof(name));
(gdb) list
50 if(file_len < 976)
51 {
52
53 fread(read_buffer, sizeof(read_buffer), 1, fp);
54 memcpy(buffer, &total_size, sizeof(total_size));
55 memcpy(buffer[sizeof(total_size)], &name, sizeof(name));
56 memcpy(buffer[sizeof(total_size)+sizeof(name)], read_buffer, sizeof(read_buffer));
57 flag = write(sock_fd, htonl(buffer), strlen(buffer));
58 if (flag < 0)
59 error("ERROR writing to socket");
buffer is an array of pointers. Is that what you intended?
Guess not
Therefore it will overrun
A number of obvious problems:
you use sizeof(read_buffer) where read_buffer is a pointer to a malloc'd buffer. This will give you the size of the pointer, not the size of the buffer.
you use strlen(buffer) when buffer contains a bunch of binary data, not a NULL terminated string. This won't work.
Related
I am trying to write data from struct into a a file. For instance the data is found in newpackets.data. I am trying to write that into a file, but keep getting segfault. I have looked at other questions on here, but could not find a solution. Adding my code below. How can i solve this issue ? Thank you
to run server do ./server 8500 1
to run client do ./client 127.0.0.1 8500 500 3 ex.txt exout.txt
ex.txt will need to be made and then write random words into it. for instance can be like 85 characters
//server side
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/socket.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h>
#include "sys/un.h"
#define MAXLINE 32768
struct ackdata
{
int ack;
};
struct packetdata
{
int seqnumber;
int lenght;
char data[MAXLINE];
int type;
};
void dg_echo (int sockfd, struct sockaddr *pcliaddr, socklen_t clilen);
int
main (int argc, char *argv[])
{
int sockfd;
struct sockaddr_in servaddr, cliaddr;
int SERV_PORT = atoi (argv[1]); ///This will grab the port to listen to
int dropc = atoi (argv[2]);
if (SERV_PORT <= 1023)
{
fprintf (stderr, "Error: Port given can not be less than 1023\n");
exit (1);
}
if (SERV_PORT > 65535)
{
fprintf (stderr,
"Error: Port given can not be more than 65535 or less than 1024\n");
exit (1);
}
sockfd = socket (AF_INET, SOCK_DGRAM, 0);
bzero (&servaddr, sizeof (servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htons (INADDR_ANY);
servaddr.sin_port = htons (SERV_PORT);
int bb = bind (sockfd, (struct sockaddr *) &servaddr, sizeof (servaddr));
if (bb < 0)
{
fprintf (stderr, "Binding failure");
}
dg_echo (sockfd, (struct sockaddr *) &cliaddr, sizeof (cliaddr));
close (sockfd);
return 0;
}
void
dg_echo (int sockfd, struct sockaddr *pcliaddr, socklen_t clilen)
{
int n;
FILE *outfile = NULL;
socklen_t len;
char mesg[MAXLINE];
struct packetdata newpackets;
char filename[MAXLINE];
recvfrom (sockfd, filename, MAXLINE, 0, pcliaddr, &len);
printf ("Name: %s", filename);
for (;;)
{
len = clilen;
//printf("HERe");
if ((outfile = fopen (filename, "a")) == NULL)
{
fprintf (stderr, "\nwriting File was not opened\n");
exit (1);
}
ssize_t rlen =recvfrom(sockfd, &newpackets, sizeof (newpackets), 0, pcliaddr, &len);
if (rlen ==-1){
printf ("failed recv");
return 1;
}
printf ("\nData: %s\n", newpackets.data);
//fprintf(outfile, "%d",newpackets.data );
fwrite(newpackets.data,rlen,1,outfile);
// sendto(sockfd, mesg, n, 0, pcliaddr, len);
}
}
Here is the client code:
//client side
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/socket.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h>
#include <math.h>
#include <sys/time.h>
#include <string.h>
#include <time.h>
#define MAXLINE 4096
#define totaltries 3
struct packetdata data (int seqnumber, int lenght, char*data);
struct packetdata
{
int seqnumber;
int lenght;
char data[MAXLINE];
int type;
};
struct ackdata
{
int ack;
int type;
};
int main (int argc, char *argv[])
{
int sockfd;
struct sockaddr_in servaddr;
FILE *infile = NULL;
int countpackets;
float calc;
int tries = 0;
int base = 0;
int sequencenumber = 0;
int datasize =0;
int winsz = atoi (argv[4]); //this is for the window size
int mtu = atoi (argv[3]); //for mtu
int SERV_PORT = atoi (argv[2]); // the port to listen to
char sendline[MAXLINE], recvline[MAXLINE];
struct packetdata forpackets;
if (mtu <= 0)
{
fprintf (stderr, "MTU Error: mtu can not be less than or equal to 0\n");
exit (1);
}
//you shouldnt use any ports from 0-1023
//1024-65535 are fines
if (SERV_PORT <= 1023)
{
fprintf (stderr, "Port Error: Port given can not be less than 1023\n");
exit (1);
}
if (SERV_PORT > 65535)
{
fprintf (stderr,
"Port Error: Port given can not be more than 65535 or less than 1024\n");
exit (1);
}
bzero (&servaddr, sizeof (servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons (SERV_PORT);
if (inet_pton (AF_INET, argv[1], &servaddr.sin_addr) <= 0)
{
fprintf (stderr, "Inet Pton error");
return 1;
}
if ((sockfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
{
fprintf (stderr, "\nsocket error\n");
return 1;
}
if ((infile = fopen (argv[5], "r")) == NULL)
{
fprintf (stderr, "\nReading File was not opened\n");
return 1;
}
//file name sending
char filename[MAXLINE];
strcpy(filename, argv[6]);
//printf("Filename: %c", filename);
sendto(sockfd, filename, MAXLINE, 0, (struct sockaddr * ) & servaddr, sizeof(servaddr));
//this is for calculations
fseek (infile, 0, SEEK_END);
countpackets = ftell (infile);
fseek (infile, 0, SEEK_SET);
// printf("countpackets %d\n",countpackets);
// printf("\nMTU %d\n",mtu);
calc = countpackets / mtu; //how many buffer is
if (countpackets % mtu)
{
calc++;
}
printf("\nCalc %f\n",calc);
char fordata[mtu];
//while(1){
while (calc>=sequencenumber && sequencenumber-base<=winsz){
fread(forpackets.data, sizeof(recvline), 1, infile);
//printf("%s", forpackets.data);
// strcpy(fordata, forpackets.data);
strncpy(fordata,(sequencenumber*mtu+forpackets.data),mtu);
printf("%s", fordata);
forpackets = data(sequencenumber,datasize, fordata );
printf("\nSending Packet: %d\n", sequencenumber);
if (sendto(sockfd, &forpackets, sizeof(forpackets), 0, (struct sockaddr * ) & servaddr, sizeof(servaddr)) == -1) {
printf("failed sending");
return 1;
}else{
sequencenumber++;
}
}
// }
close(sockfd);
fclose(infile);
}
struct packetdata data (int seqnumber, int lenght, char*data){
struct packetdata dataa;
dataa. seqnumber = seqnumber;
dataa. lenght = lenght;
dataa. type = 1;
memset(dataa.data, 0, MAXLINE);
strcpy(dataa.data, data);
return dataa;
}
Okay, just to recap the comments:
outfile was missing an fopen call, so the server fwrite would segfault
After the fix, the output file would get extraneous zeros because the length given to fwrite was the whole size rather than the returned value of recvfrom
Actually, the correct length is the length value inside the packet
You're on the right track. The struct you devised has the right things in it (e.g. sequence number, type, length, data field).
I've refactored the server and client code.
An additional issue is that the server didn't know when to stop writing the output file. There are several ways to do this. But, the one I chose was for the client to send an extra data packet with a length field of 0.
I've adjusted both client and server to do this.
Here is the refactored server code:
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/socket.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h>
#include <sys/un.h>
#define MAXLINE 32768
struct ackdata {
int ack;
};
struct packetdata {
int seqnumber;
int length;
char data[MAXLINE];
int type;
};
void dg_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen);
int
main(int argc, char *argv[])
{
int sockfd;
struct sockaddr_in servaddr, cliaddr;
#if 1
if (argc < 2) {
printf("usage: serv_port\n");
exit(1);
}
#endif
int SERV_PORT = atoi(argv[1]); // /This will grab the port to listen to
#if 0
int dropc = atoi(argv[2]);
#endif
if (SERV_PORT <= 1023) {
fprintf(stderr, "Error: Port given can not be less than 1023\n");
exit(1);
}
if (SERV_PORT > 65535) {
fprintf(stderr, "Error: Port given can not be more than 65535 or less than 1024\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htons(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
int bb = bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
if (bb < 0) {
fprintf(stderr, "Binding failure");
}
dg_echo(sockfd, (struct sockaddr *) &cliaddr, sizeof(cliaddr));
close(sockfd);
return 0;
}
void
dg_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen)
{
int n;
FILE *outfile = NULL;
socklen_t len;
char mesg[MAXLINE];
struct packetdata newpackets;
char filename[MAXLINE];
recvfrom(sockfd, filename, MAXLINE, 0, pcliaddr, &len);
#if 0
printf("Name: %s", filename);
#else
printf("Name: %s\n", filename);
outfile = fopen(filename,"w");
#endif
for (;;) {
len = clilen;
// printf("HERe");
if (recvfrom(sockfd, &newpackets, sizeof(newpackets), 0, pcliaddr, &len) == -1) {
printf("failed recv");
break;
}
printf("DEBUG: seqnumber=%d type=%d length=%d\n",
newpackets.seqnumber,newpackets.type,newpackets.length);
// end of file
if (newpackets.length == 0)
break;
//printf("\nData: %s\n", newpackets.data);
fwrite(newpackets.data, newpackets.length, 1, outfile);
// sendto(sockfd, mesg, n, 0, pcliaddr, len);
}
if (outfile != NULL)
fclose(outfile);
}
And, here is the refactored client code. I cleaned it up a bit.
I changed the code to do the fread directly into the packet struct's data field.
I changed the data function to take a pointer arg to the packet rather than returning one. This eliminates some unnecessary copying
I added an extra zero length data packet to indicate EOF
I changed the primary data read/write loop to look at the returned length from fread rather than (pre)calculate the number of packets.
//client side
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/socket.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h>
#include <math.h>
#include <sys/time.h>
#include <string.h>
#include <time.h>
#define MAXLINE 4096
#define totaltries 3
struct packetdata {
int seqnumber;
int length;
char data[MAXLINE];
int type;
};
struct ackdata {
int ack;
int type;
};
void
data(struct packetdata *pkt,int seqnumber, int length, char *data)
{
pkt->seqnumber = seqnumber;
pkt->length = length;
pkt->type = 1;
if ((length > 0) && (data != NULL))
memcpy(pkt->data, data, length);
}
int
main(int argc, char *argv[])
{
int sockfd;
struct sockaddr_in servaddr;
FILE *infile = NULL;
int countpackets;
float calc;
int tries = 0;
int base = 0;
int sequencenumber = 0;
int datasize = 0;
int winsz = atoi(argv[4]); // this is for the window size
int mtu = atoi(argv[3]); // for mtu
int SERV_PORT = atoi(argv[2]); // the port to listen to
char sendline[MAXLINE],
recvline[MAXLINE];
struct packetdata forpackets;
if (mtu <= 0) {
fprintf(stderr, "MTU Error: mtu can not be less than or equal to 0\n");
exit(1);
}
// you shouldnt use any ports from 0-1023
// 1024-65535 are fines
if (SERV_PORT <= 1023) {
fprintf(stderr, "Port Error: Port given can not be less than 1023\n");
exit(1);
}
if (SERV_PORT > 65535) {
fprintf(stderr, "Port Error: Port given can not be more than 65535 or less than 1024\n");
exit(1);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
fprintf(stderr, "Inet Pton error");
return 1;
}
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
fprintf(stderr, "\nsocket error\n");
return 1;
}
if ((infile = fopen(argv[5], "r")) == NULL) {
fprintf(stderr, "\nReading File was not opened\n");
return 1;
}
// file name sending
char filename[MAXLINE];
strcpy(filename, argv[6]);
// printf("Filename: %c", filename);
sendto(sockfd, filename, MAXLINE, 0, (struct sockaddr *) &servaddr,
sizeof(servaddr));
// this is for calculations
fseek(infile, 0, SEEK_END);
countpackets = ftell(infile);
fseek(infile, 0, SEEK_SET);
// printf("countpackets %d\n",countpackets);
// printf("\nMTU %d\n",mtu);
calc = countpackets / mtu; // how many buffer is
if (countpackets % mtu) {
calc++;
}
printf("\nCalc %f\n", calc);
// while(1){
#if 0
while (calc >= sequencenumber && sequencenumber - base <= winsz) {
#else
while (1) {
#endif
ssize_t rlen = fread(forpackets.data, 1, sizeof(forpackets.data),
infile);
data(&forpackets,sequencenumber, rlen, NULL);
printf("\nSending Packet: %d rlen=%d\n", sequencenumber,rlen);
if (sendto(sockfd, &forpackets, sizeof(forpackets), 0,
(struct sockaddr *) &servaddr, sizeof(servaddr)) == -1) {
printf("failed sending");
return 1;
}
else {
sequencenumber++;
}
if (rlen == 0)
break;
}
// }
close(sockfd);
fclose(infile);
return 0;
}
Note that the client and server are "one-shots". That is, the server exits after receiving a given file.
Also, one change I didn't make was to send/receive the filename within a packet (with a different type field).
I'd change the programs to send only packet structs.
Then, the server could have an outer loop, to service new/different requests (e.g. it could receive a file, then send a file, etc.)
With various type fields (e.g.):
send file to server (data is filename)
send file to client (data is filename)
file data (sent by client and/or server and length of 0 indicates EOF)
close connection (sent by client to server)
This may be a bit of overkill for the scope of your project ...
The server could look at the IP address from recvfrom and keep some state in a "connection" struct, based on a match to the client IP address. For example, the connection struct could hold the outfile stream (instead of a single instance).
Then, the server could handle multiple/many client streams, interspersed on the same/single socket descriptor.
UPDATE:
Hey craig. TYSM. But is there a way, where the server is not one shot go? –
juststruggle
It starts by adding my suggestion about sending the filename inside a packet with a type.
And, having the server loop do a switch (pkt.type).
I've added the ruminants of that in the code below. The client is very similar in function to before. The server will now loop after file transfer, waiting for other packets.
Note that there is a bunch of similar code between server and client. I moved some of that to a common.c file. Note that this is crude. I'd like to have a common.h for definitions and function prototypes and a common.c for common functions. But, IRL, I am being "summoned" :-) so I don't have time to fix that.
I moved the struct definition to that file. In the process, I notice that the size of the data element is different between client and server. That's a bug because type is at the end and would be elided/truncated because of the differing lengths of data
Here's common.c:
// common.c -- common code
#define MAXLINE 1024
#define totaltries 3
#ifdef DEBUG
#define dbgprt(_fmt...) printf(_fmt)
#else
#define dbgprt(_fmt...) do { } while (0)
#endif
struct packetdata {
int type;
int seqnumber;
int length;
char data[MAXLINE];
};
struct ackdata {
int ack;
int type;
};
enum {
TYPE_TOSVR,
TYPE_TOCLI,
TYPE_DATA
};
void
pktprep(struct packetdata *pkt,int type,int seqnumber, int length, char *data)
{
pkt->type = type;
pkt->seqnumber = seqnumber;
pkt->length = length;
if ((length > 0) && (data != NULL))
memcpy(pkt->data, data, length);
dbgprt("pktprep: SENDPKT seq=%d type=%d length=%d\n",
seqnumber,type,length);
}
Here is server.c:
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/socket.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h>
#include <sys/un.h>
#include "common.c"
void dg_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen);
int
main(int argc, char *argv[])
{
int sockfd;
struct sockaddr_in servaddr, cliaddr;
#if 1
if (argc < 2) {
printf("usage: serv_port\n");
exit(1);
}
#endif
int SERV_PORT = atoi(argv[1]); // /This will grab the port to listen to
#if 0
int dropc = atoi(argv[2]);
#endif
if (SERV_PORT <= 1023) {
fprintf(stderr, "Error: Port given can not be less than 1023\n");
exit(1);
}
if (SERV_PORT > 65535) {
fprintf(stderr, "Error: Port given can not be more than 65535 or less than 1024\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htons(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
int bb = bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
if (bb < 0) {
fprintf(stderr, "Binding failure");
}
dg_echo(sockfd, (struct sockaddr *) &cliaddr, sizeof(cliaddr));
close(sockfd);
return 0;
}
void
dg_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen)
{
int n;
FILE *outfile = NULL;
socklen_t len;
char mesg[MAXLINE];
struct packetdata pkt;
char filename[MAXLINE];
for (;;) {
len = clilen;
// printf("HERe");
if (recvfrom(sockfd, &pkt, sizeof(pkt), 0, pcliaddr, &len) == -1) {
printf("failed recv");
break;
}
dbgprt("DEBUG: seqnumber=%d type=%d length=%d\n",
pkt.seqnumber,pkt.type,pkt.length);
switch (pkt.type) {
case TYPE_TOSVR:
dbgprt("TOSVR: %s\n", pkt.data);
if (outfile == NULL)
outfile = fopen(pkt.data,"w");
break;
case TYPE_DATA:
// end of file
if (pkt.length == 0) {
if (outfile != NULL) {
fclose(outfile);
outfile = NULL;
}
break;
}
//dbgprt("\nData: %s\n", pkt.data);
if (outfile != NULL)
fwrite(pkt.data, pkt.length, 1, outfile);
break;
}
}
if (outfile != NULL)
fclose(outfile);
}
And, here is client.c:
//client side
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/socket.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h>
#include <math.h>
#include <sys/time.h>
#include <string.h>
#include <time.h>
#include "common.c"
int
main(int argc, char *argv[])
{
int sockfd;
struct sockaddr_in servaddr;
FILE *infile = NULL;
int countpackets;
float calc;
int tries = 0;
int base = 0;
int sequencenumber = 0;
int datasize = 0;
int winsz = atoi(argv[4]); // this is for the window size
int mtu = atoi(argv[3]); // for mtu
int SERV_PORT = atoi(argv[2]); // the port to listen to
char sendline[MAXLINE],
recvline[MAXLINE];
struct packetdata pkt;
if (mtu <= 0) {
fprintf(stderr, "MTU Error: mtu can not be less than or equal to 0\n");
exit(1);
}
// you shouldnt use any ports from 0-1023
// 1024-65535 are fines
if (SERV_PORT <= 1023) {
fprintf(stderr, "Port Error: Port given can not be less than 1023\n");
exit(1);
}
if (SERV_PORT > 65535) {
fprintf(stderr, "Port Error: Port given can not be more than 65535 or less than 1024\n");
exit(1);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
fprintf(stderr, "Inet Pton error");
return 1;
}
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
fprintf(stderr, "\nsocket error\n");
return 1;
}
if ((infile = fopen(argv[5], "r")) == NULL) {
fprintf(stderr, "\nReading File was not opened\n");
return 1;
}
// file name sending
char filename[MAXLINE];
pktprep(&pkt,TYPE_TOSVR,sequencenumber++,strlen(argv[6]) + 1,argv[6]);
// printf("Filename: %c", filename);
#if 0
sendto(sockfd, filename, MAXLINE, 0, (struct sockaddr *) &servaddr,
sizeof(servaddr));
#else
sendto(sockfd, &pkt, sizeof(pkt), 0,
(struct sockaddr *) &servaddr, sizeof(servaddr));
#endif
// this is for calculations
fseek(infile, 0, SEEK_END);
countpackets = ftell(infile);
fseek(infile, 0, SEEK_SET);
// printf("countpackets %d\n",countpackets);
// printf("\nMTU %d\n",mtu);
calc = countpackets / mtu; // how many buffer is
if (countpackets % mtu) {
calc++;
}
dbgprt("\nCalc %f\n", calc);
// while(1){
#if 0
while (calc >= sequencenumber && sequencenumber - base <= winsz) {
#else
while (1) {
#endif
ssize_t rlen = fread(pkt.data, 1, sizeof(pkt.data),
infile);
pktprep(&pkt,TYPE_DATA,sequencenumber, rlen, NULL);
if (sendto(sockfd, &pkt, sizeof(pkt), 0,
(struct sockaddr *) &servaddr, sizeof(servaddr)) == -1) {
printf("failed sending");
return 1;
}
else {
sequencenumber++;
}
if (rlen == 0)
break;
}
// }
close(sockfd);
fclose(infile);
return 0;
}
Compile server.c and client.c with -DDEBUG to start.
I have been trying to write a client and server program using C socket programming that does 2 tasks
On prompted from server -> OS command is executed in client machine
Output is stored in a file which is sent back to server. Where server reads it and displays the data plus writes the data in a file on server side.
Issue
When client sends file to the server, server does not display whole data and looks like recv() keeps waiting on socket.
Need some help
Here's the code
server code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#define SIZE 1024
void write_file(char *filename,int sockfd){
int n;
FILE *fp ;
char buffer[SIZE] ;
fp = fopen(filename, "w");
while (1) {
n = recv(sockfd, buffer, SIZE, 0);
if (n <= 0){
break;
return;
}
printf("%s", buffer) ;
fprintf(fp, "%s", buffer);
bzero(buffer, SIZE);
}
fclose(fp) ;
return;
}
int main(int argc, char *argv[]){
int portno = 7416;
int e,n,n1;
char *cmd ;
int sockfd;
struct sockaddr_in server_addr;
struct hostent *server;
char *fle = "/tmp/reposvr.";
FILE *fp;
char *num ;
if (argc < 3) {
fprintf(stderr,"usage %s hostname command \n", argv[0]);
exit(0);
}
cmd=argv[2] ;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0) {
perror("[-]Error in socket");
exit(1);
}
printf("[+]Server socket created successfully.\n");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
//server_addr.sin_family = AF_INET;
//server_addr.sin_port = port;
//server_addr.sin_addr.s_addr = inet_addr(ip);
bzero((char *) &server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(portno);
server_addr.sin_addr = *((struct in_addr *)server->h_addr);
memset(server_addr.sin_zero, '\0', sizeof server_addr.sin_zero);
e = connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if(e == -1) {
perror("[-]Error in socket");
exit(1);
}
printf("[+]Connected to Server.\n");
n = write(sockfd, cmd , strlen(cmd));
if (n < 0)
error("ERROR writing to socket");
char *filename=NULL;
filename = (char*)malloc( 50 * sizeof(char) ) ;
strcpy(filename,fle );
n1=rand();
if (asprintf(&num, "%d", n1) == -1) {
perror("asprintf");
} else {
strcat(filename, num);
printf("%s\n", filename);
free(num);
}
printf("%s\n",filename) ;
write_file(filename,sockfd) ;
printf("[+]File data sent successfully.\n");
printf("[+]Closing the connection.\n");
close(sockfd);
return 0;
}
Client code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#define SIZE 1024
void send_file(FILE *fp, int sockfd){
int n;
char data[SIZE] = {0};
while(fgets(data, SIZE, fp) != NULL) {
if (send(sockfd, data, sizeof(data), 0) == -1) {
perror("[-]Error in sending file.");
exit(1);
}
bzero(data, SIZE);
}
}
int main(){
int port = 7416;
int e,n1, n ;
FILE *fp ;
char filename[50] = "/tmp/gateway." ;
char command[50];
char *num;
FILE *pf;
char data[SIZE];
int sockfd, new_sock;
struct sockaddr_in server_addr, new_addr;
socklen_t addr_size;
char buffer[SIZE];
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0) {
perror("[-]Error in socket");
exit(1);
}
printf("[+]Server socket created successfully.\n");
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = INADDR_ANY;
e = bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if(e < 0) {
perror("[-]Error in bind");
exit(1);
}
printf("[+]Binding successfull.\n");
if(listen(sockfd, 10) == 0){
printf("[+]Listening....\n");
}else{
perror("[-]Error in listening");
exit(1);
}
addr_size = sizeof(new_addr);
while ( new_sock = accept(sockfd, (struct sockaddr*)&new_addr, &addr_size) )
{
printf("server: got connection from %s port %d\n",
inet_ntoa(new_addr.sin_addr), ntohs(new_addr.sin_port));
n = read(new_sock,buffer,1024);
if (n < 0) error("ERROR reading from socket");
strcpy(command, buffer) ;
printf("%s",command) ;
pf = popen(command,"r");
bzero(data,1024);
n1=rand();
if (asprintf(&num, "%d", n1) == -1) {
perror("asprintf");
} else {
strcat(filename, num);
printf("%s\n", filename);
free(num);
}
printf("%s",filename) ;
fp=fopen(filename,"w" );
while (fgets(data, 2048, pf) != NULL) {
printf("%s", data);
fprintf(fp, "%s",data) ;
}
fclose(fp) ;
fp = fopen(filename, "r");
if (fp == NULL) {
perror("[-]Error in reading file.");
exit(1);
}
send_file(fp, new_sock);
printf("[+]Data written in the file successfully.\n");
}
return 0;
}
Execution output
Edit
Based on the suggestions in this forum, I increased SIZE to 2048 and found that now it returns less rows and hangs after 4-5 rows itself. This is weird. I am sure it's not because of SIZE.
If you see, in client side, we are able to successfully write all in a file. Second part of the program is to read from file and send it to server. Here I am iterating through whole file and sending the data to server. The data send loop is working nicely as I have printf in same loop and we can see all data getting printed.
Looking at server side, here also we are looping till number of bytes read are < 1. Theoretically, this should work. I am sure there's some tiny silly thing that I am missing. Just not able to put my finger on it. Really need some insights in here.
Edit 2
Already tried SIZE , MSG_PEEK as you can see in comments. Any more suggestions ?
Sending a normal .txt file works perfectly fine. But if I try to send a .wav file, the output file that gets generated is only a fraction of the size of the input file (and it doesn't play anything). I've tried pretty much everything I could find on Google, it might have something to do with not reading the .wav file correctly. But I'm reading and writing one character at a time, so I don't know why that should be a problem. Also, doing this over localhost. Any help would be greatly appreciated, thank you!
server.c
/* A simple server in the internet domain using TCP
The port number is passed as an argument */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define BUFFER_SIZE 32
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, n;
socklen_t clilen, servlen;
char buffer[BUFFER_SIZE];
FILE *fp;
struct sockaddr_in serv_addr, cli_addr;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening 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);
servlen = sizeof(serv_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer, BUFFER_SIZE);
n = read(newsockfd, buffer, BUFFER_SIZE);
if (n < 0) error("ERROR reading from socket");
printf("Received file name: %s\n", buffer);
fp = fopen(buffer, "rb");
if (fp == NULL)
printf("File open failed!\n");
else
printf("File successfully opened!\n");
while (1) {
bzero(buffer, BUFFER_SIZE);
char ch;
int i;
for (i = 0; i < BUFFER_SIZE; i++) {
ch = fgetc(fp);
buffer[i] = ch;
if (ch == EOF)
break;
}
n = write(newsockfd, buffer, BUFFER_SIZE);
if (n < 0)
error("ERROR writing to socket");
if (ch == EOF)
break;
}
printf("File sending complete...\n");
if (fp != NULL)
fclose(fp);
close(newsockfd);
close(sockfd);
return 0;
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define BUFFER_SIZE 32
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[BUFFER_SIZE];
FILE *out;
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 opening 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("ERROR connecting");
printf("Enter the file name: ");
bzero(buffer, BUFFER_SIZE);
fgets(buffer, BUFFER_SIZE - 1, stdin);
buffer[strlen(buffer) - 1] = '\0';
n = write(sockfd, buffer, strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
out = fopen("out.wav", "wb");
while (1) {
bzero(buffer, BUFFER_SIZE);
int i, j;
n = read(sockfd, buffer, BUFFER_SIZE);
if (n < 0)
error("ERROR reading from socket");
char ch;
for (i = 0; i < BUFFER_SIZE; i++) {
ch = buffer[i];
if (ch == EOF)
break;
j = (int)ch;
fputc(j, out);
}
if (ch == EOF)
break;
}
printf("File write complete... You can now use the output file!!\n");
if (out != NULL)
fclose(out);
close(sockfd);
return 0;
}
To determine the end-of-transmission, you have to check the return value of read(), rather than checking for EOF in the read data.
I have also taken the liberty to restructure and simplify your code.
Consider the following (untested) changes:
server.c:
// ...
while (1) {
size_t num_read = fread(buffer, 1, BUFFER_SIZE, fp);
if (num_read == 0) // end of file.
break;
n = write(newsockfd, buffer, num_read);
if (n < 0) // Error
error("ERROR writing to socket");
else if (n == 0) // Could handle this too
break;
}
// ...
client.c:
// ...
while (1) {
n = read(sockfd, buffer, BUFFER_SIZE);
if (n < 0)
error("ERROR reading from socket");
else if (n == 0) // Socket closed. Transfer is complete (or borked)
break;
fwrite(buffer, 1, n, out); // Could check fwrite too.
}
// ...
Modify the following socket program and let the server send a file to the client.
I'm stuck with this i can't figure this out.
below is the server and client that where given to me. right now the server will send the client the time stamp.
Socket Server Example (server.c)
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
char sendBuff[1025];
time_t ticks;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n",
ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
close(connfd);
sleep(1);
}
}
Socket Client Example (client.c)
#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[])
{
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
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(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr,
sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
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");
}
}
if(n < 0)
{
printf("\n Read error \n");
}
return 0;
}
If you don't want to or can't read the whole content of the file you wish to send at once into memory, use a loop with your buffer:
#include <fcntl.h>
if (argv[1]) // or whereever you get the file name from
{
int fd = open(argv[1], O_RDONLY);
if (fd < 0) perror(argv[1]);
else
{
ssize_t n;
while (n = read(fd, sendBuff, sizeof sendBuff), n > 0)
if (send(connfd, sendBuff, n, MSG_NOSIGNAL) < 0)
{ perror("send"); break; }
close(fd);
if (n < 0) perror("read");
}
}
In the client use a similar loop. Be aware that the file might contain NUL characters, so functions like fputs, operating on C strings, are inept.
while ((n = read(sockfd, recvBuff, sizeof recvBuff)) > 0)
if (write(1, recvBuff, n) < 0) perror("write");
Read the content of the file you wish to send, and save it into a string:
char *loadFileContent(char *fileName, size_t *len){
FILE* input_file = fopen(fileName, "rb");
size_t stat;
if(!input_file){
OCSP_ERR_INDEX = OCSP_LOG_ERR_load_file_fail;
return NULL;
}
fseek(input_file, 0, SEEK_END);
long int input_file_size = ftell(input_file);
rewind(input_file);
char *file_contents = malloc((input_file_size + 1) * (sizeof(char)));
stat = fread(file_contents, sizeof(char), (size_t) input_file_size, input_file);
if(stat<1){
OCSP_ERR_INDEX = OCSP_LOG_ERR_load_file_fail;
return NULL;
}
fclose(input_file);
file_contents[input_file_size] = 0;
*len = (size_t) input_file_size;
return file_contents;
}
In your code, modify the line in server that is supposed to send response to client.
So this line write(connfd, sendBuff, strlen(sendBuff)); becomes:
size_t len;
char *text = loadFileContent("myfile.txt", &len);
write(connfd, text, len);
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a problem in linux coding.
When I send file name to server, I get the segmentation fault in server.
It may happen in read.
But, I can't find any idea to solve it.
Any suggestions?
Client Source code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#define BUFMAX 256
void error_handling(const char *msg)
{
fputs(msg, stderr);
fputc('\n', stderr);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, h_err;
int file_len = 0;
int buf_size = 0;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[BUFMAX];
FILE *file;
char *file_name;
char *file_cont;
if (argc < 2)
error_handling("ERROR! No simulator provided\n");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error_handling("ERROR opening socket\n");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_port = htons(5000);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error_handling("ERROR connecting");
// file handling
file_name = (char *)malloc(strlen(argv[1]));
file_len = strlen(argv[1]);
memcpy(file_name, argv[1], file_len);
file = fopen(file_name, "rb");
if(file == NULL)
error_handling("File is not exis!\n");
// send file name
h_err = write(sockfd, file_name, file_len);
if(h_err < 0)
error_handling("ERROR writing to socket!\n");
// file handling
fseek(file, 0, 2);
file_len = ftell(file);
fseek(file, 0, 0);
// send file size
memset(buffer, 0, BUFMAX);
sprintf(buffer, "%d", file_len);
h_err = write(sockfd, buffer, strlen(buffer));
if(h_err < 0)
error_handling("ERROR writing to socket!\n");
file_cont = (char *)malloc(file_len);
while( !feof(file) )
{
fgets(buffer, BUFMAX, file);
memcpy(file_cont + buf_size, buffer, strlen(buffer));
buf_size = strlen(buffer);
}
h_err = send(sockfd, file_cont, file_len, 0);
if(h_err < 0)
error_handling("ERROR sending to socket");
printf("File sending....\n");
fclose(file);
close(sockfd);
return 0;
}
Server Source code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define BUFMAX 8000
void error_handling(const char *msg)
{
fputs(msg, stderr);
fputc('\n', stderr);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, h_err;
int file_len = 0;
char buffer[BUFMAX];
struct sockaddr_in serv_addr, cli_addr;
FILE *file;
char *file_name;
char file_cont[BUFMAX];
socklen_t clilen;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error_handling("ERROR opening socket");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(5000);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error_handling("ERROR on binding");
listen(sockfd, 5);
clilen = sizeof(cli_addr);
while(1)
{
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error_handling("ERROR on accept");
// receive file name
memset(buffer, 0x00, BUFMAX);
h_err = read(newsockfd, buffer, BUFMAX);
if (h_err < 0)
{
close(sockfd);
close(newsockfd);
error_handling("ERROR reading from socket");
}
strcpy(file_name, buffer);
printf("File name = %s\n", file_name);
// receive file size
memset(buffer, 0, BUFMAX);
h_err = read(newsockfd, buffer, BUFMAX);
if (h_err < 0)
{
close(sockfd);
close(newsockfd);
error_handling("ERROR reading from socket");
}
file_len = atoi(buffer);
// file handling
file = fopen(file_name, "wb");
h_err = recv(newsockfd, file_cont, file_len, 0);
if(h_err < 0)
{
close(sockfd);
close(newsockfd);
error_handling("ERROR receive from socket");
}
printf("Recived client file\n");
fwrite(file_cont, 1, file_len, file);
close(newsockfd);
}
fclose(file);
close(sockfd);
return 0;
}
I tried to debug your code.
I found that you forget to allocate memory size for var "file_name" in your server code.
Try to allocate for it like following line in your code.
file_name = (char *)malloc(LEN_FILE_NAME);
The problem can be solved.