1

I am new to c programming. I tried a basic socket programming. It is working good but my problem is that I created a linked list to store the sent and received messages. When I print the linked list only sent messages(ptr3->request) is displayed and my received message (ptr3->response) is empty.

I think the passing of the arguments is where I am making mistake. But, in both case I am passing the address only. I cannot really figure out the mistake.

Code snippet:

#include<stdio.h>
#include<string.h>   
#include<sys/socket.h>
#include<arpa/inet.h> 
#include<time.h>
#include<errno.h>
#include<stdlib.h>

void create(char*,char*);
void insert(char*,char*);
void send_receive(char*,int);
void display();

struct packet_details
{
char *request;
char *response;
struct packet_details *next;
};

typedef struct packet_details details;
details *head = NULL ,*temp = NULL;

void create(char *send,char *receive)
{
    details *new_node;
    new_node= (details*)malloc(sizeof( details));

    if(NULL == new_node)
    {
        printf("Cannot allocate requested memory %d %s %s",__LINE__,__FILE__,__FUNCTION__);
    }

    else
    {
        new_node->request= send;
        new_node->response = receive;
        new_node->next = NULL;

        head = temp = new_node;
    }
}

void insert(char *send,char *receive)
{
    details *new_node;
    if(NULL == head)
    {
        create(send,receive);
        return;
    }
    new_node= (details*)malloc(sizeof( details));

        new_node->request = send;
        new_node->response = receive;
        new_node->next = NULL;

       temp->next = new_node;
       temp = new_node;
}

void display()
{
    details *ptr3;
    ptr3 = head;
    while(NULL != ptr3)
    {
        printf("\n**********************************\n");
        printf("\n**********************************\n");

        printf("\n%s",ptr3->request);
        printf("\n%s",ptr3->response);

        printf("\n***********************************\n");
        printf("\n***********************************\n");
        ptr3=ptr3->next;
    }
}

int main()
{
    int socket_desc,a=0;
    struct sockaddr_in server;
    char *message;

    //Create socket
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        printf("Could not create socket! %s\n",strerror(errno));
    }

    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_family = AF_INET;
    server.sin_port = htons(7887);

    //Connect to server
    if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0)
    {
        printf("connect error ! %s\n",strerror(errno));
        return 1;
    }

    puts("Connected\n");

    while(a < 5 )
    {
    printf("\nCLIENT:");
    message =  "Hello Server\n";
    printf("%s",message);
    send_receive(message,socket_desc);
    a++;

    sleep(10);

    printf("\nCLIENT:");
    message =  "How are you?\n";
    printf("%s",message);
    send_receive(message,socket_desc);
    a++;

    sleep(10);

    printf("\nCLIENT:");
    message =  "Are you busy?\n";
    printf("%s",message);
    send_receive(message,socket_desc);
    a++;

    sleep(10);

    printf("\nCLIENT:");
    message =  "Process my request\n";
    printf("%s",message);
    send_receive(message,socket_desc);
    a++;

    sleep(10);

    printf("\nCLIENT:");
    message =  "Bye\n";
    printf("%s",message);
    send_receive(message,socket_desc);
    a++;
    }

    close(socket_desc);
    return 0;
}


 void send_receive(char *msg,int socket_desc)
    {
    char server_reply[2000];
    char *reply;
    if(write(socket_desc,msg,strlen(msg))<0)
    {
    printf("\n data could not be sent");
    }
    read(socket_desc,server_reply,sizeof(server_reply));
    printf("server:%s",server_reply);
    reply = &server_reply[0];
    insert(msg,reply);  /* passing of two addresses as arguments */
}

Could anybody help me please?

5
  • You are probably lacking a linux tag... Commented Jul 7, 2015 at 16:48
  • char server_reply[2000] is local. the value in it will be gone once it gets out of the scope. you need to malloc a chunk of memory every time you receive a message. and reply = &server_reply[0]; is unnecessary too. Commented Jul 7, 2015 at 16:52
  • TL;DR. Please provide a MCVE Commented Jul 7, 2015 at 16:52
  • @HuStmpHrrr Thank you . I understand that reply = &server_reply[0]; is unnecessary. But can you ellaborate on using that malloc. I am sorry , i am new to programming.. Commented Jul 7, 2015 at 16:59
  • @SRA the answer down there is correct. strdup calls malloc in the background. Commented Jul 7, 2015 at 17:04

1 Answer 1

3

Every time you call insert, you're passing in the address of a buffer that was allocated on the stack, i.e. server_reply, and saving that in your list. Then, when send_receive exist, that memory points to garbage.

Instead of doing this:

new_node->request= send;
new_node->response = receive;

Do this:

new_node->request= strdup(send);
new_node->response = strdup(receive);

That makes a copy of the sent/recieved data in a newly allocated buffer. Just be sure to free() all of that memory when you clean up.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.