1

I have made a client server program that accepts 4 arguments. Input file, output file, IP Add, port number. But i am getting segmentation fault when trying to send an ending character.

server.cpp

#include <unistd.h>
#include <iostream>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <fstream>
#include <iomanip>
using namespace std;

int main (int argc, char **argv)
{
    int sock, cli, read_size, file_size;    //cli socket descriptor
    struct sockaddr_in server, client;
    char *send_buffer;
    char *fname;

    unsigned int sock_len;
    ofstream fout;

    cout << "Initializing a Socket\n";
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("Socket: ");
        close(sock);
        exit(-1);
    }
    server.sin_family = AF_INET;
    server.sin_port = htons(7246);
    server.sin_addr.s_addr = INADDR_ANY;
    bzero(&server.sin_zero, 0);

    sock_len = sizeof(struct sockaddr);

    cout << "Binding a Socket\n";
    if((bind(sock, (struct sockaddr *)&server, sock_len)) == -1)
    {
        perror("Bind: ");
        close(sock);
        exit(-1);
    }

    cout << "Listening\n";
    if((listen(sock, 5)) == -1)
    {
        perror("Listen: ");
    }

    //To accept connection and get data from server

    while(1)
    {
        cout << "Waiting...";
        if((cli = accept(sock, (struct sockaddr *)&client, &sock_len )) == -1)
        {
            perror("Accept: ");
            close(sock);
            exit(-1);
        }
        else
        {
            cout << "Server: Got connection from " << inet_ntoa(client.sin_addr) << endl;

            file_size = recv(cli, fname, 100, 0);
            cout << "\nOpening file\n";
            fout.open(fname, ios::out | ios::app | ios::binary);
            if(!fout)
            {
                cout << "Error opening the file " <<fname << endl;

                close(sock);
                exit(1);
            }
        }
        cout << "Start now\n";
        //while((recv(cli, send_buffer, sizeof(send_buffer), 0)) != EOF)
        //while(*send_buffer != EOF)
        while(strcmp(send_buffer, "_EOF_") != 0)
        {
            recv(cli, send_buffer, 10, 0);
            cout << "Receiving Msg...";
            fout.write(send_buffer, sizeof(send_buffer));
            /*if(*send_buffer == EOF)   {
                cout << "Data Received\n";
                close(sock);
                break;

            }*/
        }
        //fout.write(EOF, sizeof(EOF));
        /*if(read_size == 0)
        {
            cout << "Client Disconnected";
        }
        else if(read_size == -1)
        {
            perror("Receive Failed");
            close(sock);
        }*/
        //  fout.write(eof, sizeof(eof()));
        fout.close();


    }
    close(sock);
    return 0;
}

Also client.cpp

/*  
Authors: Manoj Parihar
Description: This program
*/

#include <unistd.h>
#include <iostream>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <fstream>
#include <iomanip>
#include <netdb.h>
using namespace std;

int main (int argc, char *argv[])
{
    int sockfd, numbytes;
    char *buf_msg;
    struct sockaddr_in server_add;
    struct hostent *he;
    char *end = "_EOF_";
    ifstream fin;

    if(argc != 5)
    {
        perror("Credentials Incomplete... Try again");
        exit(1);
    }
    /*if ((he = gethostbyname(argv[1])) == NULL)    {
        cout << "Cannot get hostname" << endl;
        exit(1);
    }*/
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        cout << "Socket Failure..." << endl;
        close(sockfd);
        exit(1);
    }
    memset(&server_add, 0, sizeof(server_add));
    server_add.sin_family = AF_INET;
    server_add.sin_port = htons(atoi(argv[4]));
    server_add.sin_addr.s_addr = inet_addr(argv[3]);
    bzero(&server_add.sin_zero, 0);

    cout << "Trying to connect\n";
    if(connect(sockfd, (struct sockaddr *)&server_add, sizeof(struct sockaddr)) == -1)
    {
        perror("Connect Error");
        close(sockfd);
        exit(1);
    }
    else
        cout << "sending filename...\n";
    send(sockfd, argv[2], strlen(argv[2]), 0);


    cout << "opening: " << argv[1] << strlen(argv[1]) << endl;
    fin.open (argv[1], ios::in | ios::app | ios::binary);
    if(!fin)
    {
        cout << "Client: Error opening file" << endl;
        close(sockfd);
        exit(1);
    }
    while(!(fin.eof()))
    {
        fin.read(buf_msg, 10);

        cout << buf_msg << sizeof(buf_msg) << endl;
        if(send(sockfd, buf_msg, sizeof(buf_msg), 0) == -1)
        {
            cout << "Failure Sending Msg";
            close(sockfd);
            exit(1);
        }
    }
    cout << "Sending end character\n";
    if(send(sockfd, "_EOF_", 5, 0) == -1)
    {
        cout << "Endpoint not sent\n";
        close(sockfd);
        exit(1);
    }
    //send(sockfd, -1, sizeof(int), 0)
    cout << "Closing Client...";
    close(sockfd);
    return 0;
}
ashiquzzaman33
  • 5,451
  • 5
  • 29
  • 39

1 Answers1

1

Segmentation fault means your program are accessing memory locations that are not meant for it to access. This usually means you have pointers that are not properly initialized or points to memory blocks that are already returned back to the OS.

You must allocate memory for your send_buff and buf_msg before using them.

void* malloc (size_t size);

Allocate memory block

Allocates a block of size bytes of memory, returning a pointer to the beginning of the block.

Something like:

char *send_buff = malloc(1024);
char *buf_msg = malloc(1024);
Community
  • 1
  • 1
xiaofeng.li
  • 7,284
  • 2
  • 20
  • 29
  • 1
    He also must fix the way `sizeof(buf_msg)` and `sizeof(send_buffer)` are used. These both always give the size of any pointer, not how full of bytes the buffers are. – Christopher Oicles Oct 13 '15 at 23:44