How can I solve the segmentation fault in socket programing? [closed] - c

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.

Related

linking errors : undefined reference to `__imp_socket'

I have a simple client-server program in C, I am trying to compile it using GCC (the latest version) on windows10 but I am getting some linking errors like
undefined reference to `__imp_socket'
undefined reference to `__imp_htons'
undefined reference to `__imp_bind'
undefined reference to `__imp_listen'
undefined reference to `__imp_accept'
undefined reference to `__imp_gethostbyname'
undefined reference to `__imp_connect'
I've tried adding -lws2_32 with no luck; i.e. it still can't find the references. Can anyone else think of anything else I might be missing?
server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <winsock2.h>
#include <windows.h>
// system file contains definations of system calls
// include<sys/socket.h>
#include <winsock.h>
//#inlude<netinet/in.h>
#include <ws2tcpip.h>
#include <ws2ipdef.h>
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
if (argc < 2)
{
fprintf(stderr, "Port number not provided. program terminated\n");
exit(1);
}
int sockfd, newsockfd, portno, n;
char buffer[255];
struct sockaddr_in serv_addr, cli_addr;
socklen_t clilen;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
error("Error opening Socket.");
}
// memset((char *)&serv_addr, sizeof(serv_addr));
memset((char *)&serv_addr, 0, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.S_un.S_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
error("Binding Failed.");
}
listen(sockfd, 5);
// 5 is the number of cilents that can connect at the moment
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
if (newsockfd < 0)
{
error("Error while accepting");
}
while (1)
{
memset(buffer, 0, 256);
n = read(newsockfd, buffer, 255);
if (n < 0)
{
error("Error while reading the message");
}
printf("Client : %s\n", buffer);
memset(buffer, 0, 255);
fgets(buffer, 255, stdin);
n = write(newsockfd, buffer, strlen(buffer));
if (n < 0)
{
error("Error while writing");
}
int i = strncmp("Bye", buffer, 3);
if (i == 0)
{
break;
}
}
close(newsockfd);
close(sockfd);
return 0;
}
client
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
// read write
#include <sys/types.h>
#include <winsock2.h>
#include <windows.h>
// system file contains definations of system calls
// include<sys/socket.h>
#include <winsock.h>
//#inlude<netinet/in.h>
#include <ws2tcpip.h>
#include <ws2ipdef.h>
// #include <netdb.h>
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[255];
if (argc < 3)
// if less than 3 host has not provided port no.
{
fprintf(stderr, "usage %s hostname port\n", argv[0]);
exit(1);
}
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");
}
memset((char *)&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memcpy((char *)server->h_addr_list, (char *)&serv_addr.sin_addr.S_un.S_addr, server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
error("Connection failed");
}
while (1)
{
memset(buffer, 0, 255);
fgets(buffer, 255, stdin);
n = write(sockfd, buffer, strlen(buffer));
if (n < 0)
{
error("Error while writing");
}
memset(buffer, 0, 255);
n = read(sockfd, buffer, 255);
if (n < 0)
{
error("Error while reading");
}
printf("Server: %s", buffer);
int i = strncmp("Bye", buffer, 3);
if (i == 0)
{
break;
}
}
close(sockfd);
return 0;
}

Sending an audio file over TCP using sockets in C

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 c socket program to send file from server to client

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);

Multiple connections to server via socket in C

Basically my program is suppose to be able to have multiple connections to a server at the same time. Which I have running, except when they have to send large amounts of text via a socket, then it is unpredictable. Sometimes it works, sometimes not. The plaintext4 file is 69,333 bytes long, when I try to send it 5 times at the same time over the network via a socket to a server and back, it doesn't work always; sometimes it works, sometimes parts of it is missing, etc. When I used basically the same thing using write and read it worked, but when I tried to the same with large amounts of text, it didn't work almost at all, hence why I switched to send and recv. Now I can't figure out how to make it so when someone is sending sometime, no one else will send at the same time... because I think that is the problem I am having. Any help would great.
The status of my program right now:
- Works when sending small amounts of text.
- Doesn't work when sending large amounts of text.
- The size of the file that it creates when it doesn't work can vary, sometimes is above 60K bytes sometimes as little as 20K bytes. Meaning that probably one of the other processes wrote to the socket or read from it before the correct process got to receive it. (I think).
server code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
const int BUFF_SIZE = 70000;
int sockfd, newsockfd, portno, newsockfdc;
socklen_t clilen;
char buffer[BUFF_SIZE];
pid_t pid;
int status;
char temp[BUFF_SIZE];
struct sockaddr_in serv_addr, cli_addr;
int n;
int i;
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);
while(1){
waitpid(-1, &status, WNOHANG);
memset(buffer, '\0', sizeof(buffer));
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
if((pid=fork())==0)
{
close(sockfd);
int d;
for(i=0; i<1; i++)
{
bzero(buffer,BUFF_SIZE);
//sleep(1);
d=BUFF_SIZE-1;
//n = read(newsockfd,buffer,d);
n = recv(newsockfd, buffer, sizeof(buffer), 0);
if (n < 0) error("ERROR reading from socket");
bzero(temp, BUFF_SIZE);
strcpy(temp, buffer);
n = send(newsockfd, buffer, strlen(buffer)+1, 0);
//n = write(newsockfd,temp,sizeof(temp));
if (n < 0) error("ERROR writing to socket");
}
close(newsockfd);
exit(0);
}
else{
waitpid(-1, &status, WNOHANG);
close(newsockfd);
}
}
close(sockfd);
return 0;
}
client 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>
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;
const int BUFF_SIZE = 70000;
char buffer[BUFF_SIZE];
if (argc < 4) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
int numt;
numt = atoi(argv[3]);
char numc[5];
bzero(numc, 5);
sprintf(numc, "%d", numt);
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");
bzero(buffer,BUFF_SIZE);
FILE *fp;
size_t bytes_read;
if((fp=fopen("./plaintext4", "r+"))==NULL)
{
perror("fopen(2) file error");
exit(EXIT_FAILURE);
}
bytes_read = fread(buffer, sizeof(buffer), 1, fp);
fclose(fp);
sleep(1);
n=send(sockfd, buffer, strlen(buffer)+1, 0);
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,BUFF_SIZE);
n=BUFF_SIZE - 1;
n = recv(sockfd, buffer, sizeof(buffer), 0);
if (n < 0)
error("ERROR reading from socket");
char filei[90];
bzero(filei,90);
strcpy(filei, "plaintext");
strcat(filei, numc);
strcat(filei, "_a");
if((fp=fopen(filei, "w+"))==NULL)
{
perror("fopen(2) file error");
exit(EXIT_FAILURE);
}
bytes_read = fwrite(buffer, strlen(buffer), 1, fp);
fclose(fp);
close(sockfd);
return 0;
//sleep(1);
printf("Sending message 1: plaintext1\n");
bzero(buffer,BUFF_SIZE);
if((fp=fopen("./plaintext1", "r+"))==NULL)
{
perror("fopen(2) file error");
exit(EXIT_FAILURE);
}
bytes_read = fread(buffer, sizeof(buffer), 1, fp);
fclose(fp);
n = send(sockfd, buffer, strlen(buffer)+1, 0);
//n = write(sockfd, buffer, strlen(buffer));
if (n < 0)
error ("ERROR writing to socket client side");
bzero(buffer, BUFF_SIZE);
n=BUFF_SIZE - 1;
n = recv(sockfd, buffer, sizeof(buffer), 0);
//n = read(sockfd, buffer, n);
if (n < 0)
error("ERROR reading from socket client side");
printf("message: %s\n", buffer);
strcat(filei, "b");
if((fp=fopen(filei, "w+"))==NULL)
{
perror("fopen(2) file error");
exit(EXIT_FAILURE);
}
bytes_read = fwrite(buffer, strlen(buffer), 1, fp);
fclose(fp);
close(sockfd);
return 0;
}
You server process can (which process accept() call) can be blocked by waitpid - it is can be cause of your problem.
Alternatively you can implement waitpid call via SIGCHLD signal handler and remove waitpid from main().
Best regards!

segmentation fault sockets in c

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.

Resources