Darakian
Darakian

Reputation: 659

TCP sockets in c

I'm attempting to write a TCP socket interface for my program and I'm pulling my hair out with an accept() error (I think). For this I've created some boiled down test code.
First I do a little set up

int server_socket = 0;
server_socket = socket(AF_INET, SOCK_STREAM, 0);

int accepted_connection = 0;

struct sockaddr_in server_address;
server_address.sin_port = htons(9001);
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;

struct sockaddr_in client_address;
client_address.sin_port = 0;
client_address.sin_family = AF_INET;

char * server_socket_read_buffer[100] = {0};
int server_socket_read_length = 0;

All pretty simple stuff. Just allocate some variables. Next I bind and listen

if (bind(server_socket,(struct sockaddr *)&server_address, sizeof(server_address)) < 0)
{
    perror("Bind() on server_socket has failed\n");
}

if (listen(server_socket, 10) < 0)
{
    perror("Listen() on server_socket has failed\n");
}

Next is the part where I believe I have my problem

printf("Attempting accept!\n");
if (accepted_connection = accept(server_socket, (struct sockaddr *)NULL, NULL) < 0)
{
    perror("Accept failed\n");
}
sleep(10);
if (server_socket_read_length = read(accepted_connection, &server_socket_read_buffer, server_socket_read_length) < 0)
{
    perror("Read failed\n");
}
printf("Read %d bytes from socket\n", server_socket_read_length);
for (int i = 0; i<server_socket_read_length;i++)
{
    printf("%x\n",server_socket_read_buffer[i]);
}

This compiles and runs. When I use nc with the command 'nc 127.0.0.1 9001' I get a connection, but no data is read. In particular I get 0 bytes of data. I thought this might be due to the NULLs in the accept line, but changing those to a proper struct and length prevent my code from compiling.

If anyone can shed some light on what I'm doing wrong I would be very grateful.

Upvotes: 1

Views: 274

Answers (3)

Darakian
Darakian

Reputation: 659

So after more struggle I found my final answer. The block

    if (accepted_connection = accept(server_socket, (struct sockaddr *)NULL, NULL) < 0)
    {
    //code
    }

Doesn't work. My read later on was blocking because accepted_connection wasn't a valid socket. Changing to

    (accepted_connection = accept(server_socket, (struct sockaddr *)NULL, NULL);
    if accepted_connection < 0)
    {
    //code
    }

resolved my issue. As far as I can gather the file descriptor wasn't being created inline with the if() and reading data from an integer isn't very helpful.
Thanks for the input everyone.

Upvotes: 0

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136505

There are a couple of errors:

  1. INADDR_ANY is in host byte order and needs to be converted to network one like htonl(INADDR_ANY). But it does not matter since constant INADDR_ANY is defined as 0.

  2. This

    char * server_socket_read_buffer[100]
    

    should be

    char server_socket_read_buffer[100]
    
  3. This

    read(accepted_connection, &server_socket_read_buffer, server_socket_read_length)
    

    should be

    read(accepted_connection, server_socket_read_buffer, sizeof server_socket_read_buffer)
    

Upvotes: 1

usr
usr

Reputation: 171246

You are passing in server_socket_read_length = 0 which causes a maximum read length of zero. Pass the buffer size. The declaration of server_socket_read_buffer is incorrect as well. Probably you should allocate a bigger buffer (like 4KB) on the heap.

Also remove the sleep.

The rest is probably working because nc obtains a connection and you are able to accept and read without error.

Upvotes: 1

Related Questions