Home > Enterprise >  socket code only works on a 16 byte buffer
socket code only works on a 16 byte buffer

Time:09-17

I am having difficulty changing the amount of data my server sends and getting it to send data. This code fails, but works when I change the size of buffer to 16 characters.

This is the code from transferclient.c

#include <errno.h>
#include <getopt.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define BUFSIZE 218

int main(int argc, char **argv) {
  unsigned short portno = 10823;

    int sock = 0;
    struct sockaddr_in serv_addr;
    char buffer[32] = {0};
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("\n Socket creation error \n");
        return -1;
    }

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(portno);
    printf("Attemping to connect\n");
    if (connect(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
    {
        printf("\nConnection Failed \n");
        return -1;
    }
    printf("Connected\n");
    read(sock, buffer, 16);
    return 0;
}

This is the code from transferserver.c

#include <errno.h>
#include <getopt.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define BUFSIZE 218

int main(int argc, char **argv) {
  int portno = 10823;          /* port to listen on */

    int server_fd, new_socket;
    struct sockaddr_in address;
    int opt =1;
    int addrlen = sizeof(address);

    // Creating socket file descriptor
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
    {
        perror("socket failed");
      exit(EXIT_FAILURE);
    }

    // Attaching the socket to the port
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)))
    {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(portno);
   
   
    // Forcefully attaching socket to the port
    if (bind(server_fd, (struct sockaddr *) &address, sizeof(address))<0)
    {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }
    if (listen(server_fd, 3) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }
    printf("Listening\n");
    
    while ((new_socket = accept(server_fd, (struct sockaddr *) &address, (socklen_t*) &addrlen)) > 0)
    {
        printf("%d\n", new_socket);
        printf("Socket connected\n");
    }
    return 0;
}

Server side

Listening

4

Socket connected


***Client Side***
``` 
Attemping to connect

Connected

When I change the line in transferclient.c to 32 bytes.

char buffer[32] = {0};

The sockets fail to connect.

Server side

Listening

Client Side

Attemping to connect

Why is that?

CodePudding user response:

In the client code, you don't seem to be setting all fields of serv_addr.

struct sockaddr_in serv_addr;

[...]

serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portno);

Because you are not setting serv_addr.sin_addr, it will have an indeterminate (garbage) value when you pass it to the function connect.

My guess is that changing the size of the array caused the sin_addr field of serv_addr to have a different initial (garbage) value. That is why the code works when buffer has a size of 16 but fails when it has a size of 32.

CodePudding user response:

In my opinion... apart of what has already been mentioned in other answers, you are lacking constants... you should define something like:

#define BUFFER_SIZE    (32)

and then use

    char buffer[BUFFER_SIZE];

and

    read(sock, buffer, BUFFER_SIZE);

or, if you don't like this approach, use this other:

    char buffer[32];

and later

    read(sock, buffer, sizeof buffer);

but if you put different numbers in the buffer size and in the read() call it is normal that it doesn't work ok when you call read() with 16 as the number of characters to read.

By the way, it is common that you ask a socket to read a fixed amount of bytes, and it returns less bytes than the amount you requested, so IT IS VERY IMPORTANT THAT YOU CHECK THE RETURN VALUE OF read(2). Something like:

    ssize_t n = read(sock, buffer, BUFFER_SIZE);

as from buffer[n] to buffer[sizeof buffer - 1] there can be nothing useful to your code (rests of a previous read, or similar) It is quite common to print it with something like:

    if (n > 0)
        printf("Read: [%.*s]\n", n, buffer);

that will print that number of received valid characters, and not what is behind them in the buffer.

  • Related