1
\$\begingroup\$

I have written a simple server to host my page and CSS (CSS file is 22KB).

Using sockets and TCP. Can any one please review it and give feedback on how can I make my server reliable using TCP and other C related feedback.

#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>

//aaa
#define PORT 80
#define BUF_SIZE 20000

#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2

int min(int a, int b)
{
    return a>b?b:a;
}

int process(int size,char buffer[size],char status)
{
    int i=0;
    int line_len=0;
    char *line=malloc(sizeof(char) *150);

    while(i<size)
    {
        if(strncmp((void *)&buffer[i],"style9.css",strlen("style9.css"))==0)
        return 3;

        if(strncmp((void *)&buffer[i],"GET / HTTP/1.1",14)==0)
        {
          
           while(buffer[i]!='\n')
           {
            line[line_len]=buffer[i];
            line_len++;
            i++;

           }

           //line[line_len]='\0';
           //printf("%s\n",line);
           memset(line,0,line_len);

           line_len=0;
           return 2; 
        }


        i++;
        line_len++;
    }

    return 2;

}
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
{
    off_t orig;

    if (offset != NULL) {

        /* Save current file offset and set offset to value in '*offset' */

        orig = lseek(in_fd, 0, SEEK_CUR);
       
        if (orig == -1)
            return -1;
        if (lseek(in_fd, *offset, SEEK_SET) == -1)
            return -1;
    }

    size_t totSent = 0;

    while (count > 0) {
        size_t toRead = min(BUF_SIZE, count);

        char buf[BUF_SIZE];
        ssize_t numRead = read(in_fd, buf, toRead);
        if (numRead == -1)
            return -1;
        if (numRead == 0)
            break;                      /* EOF */

        ssize_t numSent = write(out_fd, buf, numRead);
        if (numSent == -1)
            return -1;
        if (numSent == 0)               /* Should never happen */
            printf("fatal: should never happen");
            //fatal("sendfile: write() transferred 0 bytes");

        count -= numSent;
        totSent += numSent;
    }

    if (offset != NULL) {

        /* Return updated file offset in '*offset', and reset the file offset
           to the value it had when we were called. */

        *offset = lseek(in_fd, 0, SEEK_CUR);
        if (*offset == -1)
            return -1;
        if (lseek(in_fd, orig, SEEK_SET) == -1)
            return -1;
    }

    return totSent;
}


int main(int argc, char const *argv[])
{
    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[1000] = {0};
    int get_return321;
    //GET /css/style.css HTTP/1.1
    char *hello = "HTTP/1.1 200 Okay\r\nContent-Type: text/html; charset=ISO-8859-4 \r\n\r\n";
    //"HTTP/1.1 200 OK\\r\\n" \
            "Content-Length: 55\r\n\n Content-Type: application/json\r\n '{\"name\":\"fawad\"}'";
    
    
    //struct stat sb;
    char *hello1 = "HTTP/1.1 200 Okay\r\nContent-Type: text/css\r\n\r\n";
    struct stat sb_html;
    struct stat sb_css;     
    int fd_in_html;//=open("/home/fawad/Desktop/C-work/html9.html",O_RDONLY);
    const char* filename_html="/home/fawad/Desktop/C-work/html9.html";
    
    int fd_in_css;//=open("/home/fawad/Desktop/C-work/css/style9.css",O_RDONLY);
    const char* filename_css="/home/fawad/Desktop/C-work/css/style9.css";

    
    

    
    //printf("%lu\n",sb_css.st_size);
    

    
            
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
    {
        perror("socket failed");
        //exit(EXIT_FAILURE);
    }
    
    
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,&opt, sizeof(opt)))
    {
        perror("setsockopt");
        //exit(EXIT_FAILURE);
    }

       /*if( setsockopt(server_fd, SOL_SOCKET, SO_SNDBUF, &sb.st_size, sizeof(sb.st_size)))
        {
        printf("sockopt\n");
        }*/
        
        /*int state = 1;
    if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &state, sizeof(state)))
    {
        printf("sockopt\n");
    }*/
    
    int state = 1;
    if(setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state)))
    {
        printf("TCP CORK\n");
    }

    

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons( 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);
    }
    
    
    while(1)
    {
        printf("in loop\n");
    
    
    
        if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
                            (socklen_t*)&addrlen))<0)
        {

        //  exit(EXIT_FAILURE);
        }
    
        
    
    
    
             printf("request came\n");
    
    
        valread = read( new_socket , buffer, (1000));


        
        //printf("%s\n",buffer );
        printf("_________________________________\n");
        get_return321=process(900,buffer,'r');
        buffer[499]='\0';
        printf("\n");
        printf("\n");
        
        
        if(get_return321==2)
        {
            
            

            send(new_socket , hello , strlen(hello) , 0 );
            //send(new_socket , buffer_html , sb_html.st_size , 0 );
            fd_in_html=open("/home/fawad/Desktop/C-work/html9.html",O_RDONLY);
            if (stat(filename_html, &sb_html) == -1) 
            {
                printf("%d\n",errno);
                //exit(EXIT_FAILURE);
            }
            sendfile(new_socket,fd_in_html,0,sb_html.st_size);
            close(fd_in_html);
            printf("html sent\n");
            

        }   
        if(get_return321==3)
        {
            send(new_socket , hello1 , sb_css.st_size , 0 );
            fd_in_css=open("/home/fawad/Desktop/C-work/css/style9.css",O_RDONLY);
            if (stat(filename_css, &sb_css) == -1) 
            {
                printf("%d\n",errno);
                //exit(EXIT_FAILURE);
            }
            sendfile(new_socket,fd_in_css,0,sb_css.st_size);
            printf("3 reached\n");
            close(fd_in_css);
            

        }
        close(new_socket);
        state = 0;
        setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
        //close(new_socket);            
        state = 1;
        setsockopt(server_fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));



    }
    
    //close(fd_in);
    close(fd_in_html);  
       
}
\$\endgroup\$
2
  • \$\begingroup\$ question code edited \$\endgroup\$
    – user786
    Sep 16, 2021 at 16:16
  • \$\begingroup\$ Sendfile function is system call code from a book \$\endgroup\$
    – user786
    Sep 16, 2021 at 16:56

1 Answer 1

1
\$\begingroup\$

Some basic code-hygiene:

  • Be consistent with formatting. Using different numbers of spaces for indenting is very sloppy. Personally I'd suggest "tabs for indent, and spaces for alignment", but what really matters is consistency.

  • Don't insert random gaps of vertical whitespace. It makes the code a lot harder to read and understand. If you feel that certain sections need to be split up, consider putting them in separate functions.

  • Don't leave commented-out code in your programs. You should be using git or another version control system, which allows you to easily go back to an earlier version if something breaks. Any code that isn't currently used in the program can then be safely deleted.

  • Declare variables as close as possible to where they are used, not at the start of the function.

  • Memory allocated with malloc must be freed with free when it's no longer needed to avoid leaking memory. (Note that a fixed-size buffer of 150 chars would be fine on the stack).

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.