Click here to Skip to main content
15,884,298 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am implenting multi-threaded web-server I initially tested for single connection without threads and I could decode request and send the file .All html pages are correctly displayed but browser says gif is corrupted.The send API returns the same no of bytes that I sent.

The send function works for html but sends corrupt images for gif.The send API does return the same bytes that i send so why is the image corrupted.The mode i believe is binary for reading the file.Its ubuntu 12.04 x86 g++/gcc 4.7.2
Plz identify the problem if possible.


C++
#include <iostream>
#include <list>
#include "network.h"
#include <pthread.h>
#include <fstream>
#include <ctype.h>
#include <inttypes.h>
#include "http.h"
#include <string>



using namespace std;

int sockfd;
int i;


char dir[2000];

pthread_mutex_t elock;
pthread_cond_t cwait;
pthread_mutex_t llock;


class clist
{
public:
    int sock;
    bool req;
    char ext[200];
    char path[2000];
    int fsize;
} obj;

list <clist> cl;
list<clist>::iterator it;

bool compare(const clist& lhs, const clist& rhs)
{
    return lhs.fsize < rhs.fsize;
}

void tok_req(char *);
void get_size();
void process_req(clist *);
pthread_t td;

void * exect(void*)
{
    while(1)
    {
        pthread_mutex_lock(&llock);
        if (cl.empty())
        {
            pthread_cond_wait(&cwait,&llock);
        }
        clist *obj1;
        //obj1=new obj;
        *obj1=cl.front();
        process_req(obj1);
        free(obj1);
        pthread_cond_signal(&cwait);
        pthread_mutex_unlock(&llock);
    }
    return NULL;
}

void * sched(void*)
{
    sleep(20);
    while(1)
    {
        pthread_mutex_lock(&llock);
        if (cl.empty())
        {
            pthread_cond_wait(&cwait,&llock);
        }
        cl.sort(compare);
        it=cl.begin();
        for(; it!=cl.end(); it++)
        {
            cout<<it->sock<<" ";
            cout<<it->req<<" ";
            cout<<it->path<<" ";
            cout<<it->ext<<" ";
            cout<<it->fsize<<endl;
        }
        pthread_cond_signal(&cwait);
        pthread_mutex_unlock(&llock);
    }
    return NULL;
}

//thread t1(process_req);

int main(int argc,char *argv[])
{

    //daemon(2,2);
    n=atoi(argv[1]);
    pthread_t sid;
    int const tno=n;
    pthread_t tid[tno];
    //Thread create
    for  (i=0; i<n; i++)
    {
        pthread_create(&tid[i],NULL,&exect,NULL);
    }
    pthread_create(&sid,NULL,&sched,NULL);
    //Start Listening
    servcl_memset();
    sock_create();
    sock_bind();
    set_listen();
    char buf[1024];

    while(1)
    {
        cout<<"Hello"<<endl;
        strcpy(dir,"");
        strcpy(dir,argv[2]);
        sockfd=accept(listen_sd,(sockaddr *)&remoteaddr,&addrlen);
        pthread_mutex_lock(&llock);
        obj.sock=sockfd;
        if (sockfd == -1)
            perror("accept");
        //while(1){
        memset(buf,0,sizeof buf);
        recv(sockfd,buf,sizeof buf,0);
        tok_req(buf);
        get_size();
        //process_req();

        cl.push_back(obj);
        //pthread_cond_signal(&cwait);
        pthread_mutex_unlock(&llock);
    }
    close(sockfd);
    close(listen_sd);//process_req();
    return 0;
}





void tok_req(char *s)
{
    char *p1;
    char *p2;

    p1=strtok(s," ");

    if (strcasecmp(p1,"GET")==0)
        obj.req=0;
    if (strcasecmp(p1,"HEAD")==0)
        obj.req=1;

    p1=strtok(NULL," ");
    //p3=strtok(NULL,"/");
    strcpy(obj.path,p1);
    strcat(dir,obj.path);
    strcpy(obj.path,dir);
    //Get extension
    p2=strtok(p1,".");
    p2=strtok(NULL,".");
    strcpy(obj.ext,p2);
    //cout<<obj.path<<endl;
}


void get_size()
{
    ifstream h;
    h.open(obj.path,ios_base::in|ios::binary);
    h.seekg(0,ios::end);
    obj.fsize=h.tellg();
    h.close();
}

void process_req(clist *obj)
{
    char buf[obj->fsize];
    ifstream h;
    h.open(obj->path,ios::binary|ios_base::in);
    if ( (strcmp(obj->ext,"html") ==0) || (strcmp(obj->ext,"htm")==0) )
    {
        send(obj->sock,TXT,sizeof TXT,0);
        h.read(buf,obj->fsize);
        h.close();
        send(obj->sock,buf,obj->fsize,0);
        close(obj->sock);
        return;
    }

    else
    {
        memset(buf,0,sizeof buf);
        h.read(buf,obj->fsize);
        h.close();
        send(obj->sock,GIF,sizeof GIF,0);
        send(obj->sock,buf,obj->fsize,0);
        close(sockfd);
        return;
    }


}

void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET)
    {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }
    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

unsigned int get_in_port(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET)
    {
        return (((struct sockaddr_in*)sa)->sin_port);
    }
    return (((struct sockaddr_in6*)sa)->sin6_port);
}


void servcl_memset()
{
    memset(&hints, 0, sizeof(hints));
    hints.ai_family= AF_INET;
    hints.ai_socktype=SOCK_STREAM;
    hints.ai_flags=AI_PASSIVE;
}

void sock_create()
{

    if ((info = getaddrinfo(NULL, PORT, &hints, &loadinfo)) != 0)  //Detect PORT IP available
    {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(info));
        return;
    }

    if ((listen_sd = socket(loadinfo->ai_family, loadinfo->ai_socktype,loadinfo->ai_protocol)) == -1)  //Socket create
    {
        perror("server: socket");
        return;
    }

    info = setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR,&yes, sizeof(int));
    if (info < 0)
    {
        perror("setsockopt() failed");
        close(listen_sd);
        return;
    }


}



void sock_bind()
{
    info= bind(listen_sd,loadinfo->ai_addr,loadinfo->ai_addrlen);
    if (info < 0)
    {
        perror("bind() failed");
        close(listen_sd);
        return;
    }
}

void set_listen()
{
    info = listen(listen_sd, n);
    if (info < 0)
    {
        perror("listen() failed");
        close(listen_sd);
        exit(-1);
    }
}
Posted
Updated 23-Oct-13 6:51am
v2
Comments
Richard MacCutchan 23-Oct-13 12:23pm    
Please indent your code properly so it is readable, and show exactly where the failing line or lines are.
ksoftj 27-Oct-13 10:22am    
I have highlighted the send function in process_req() function
Richard MacCutchan 27-Oct-13 12:12pm    
Fine, have you tested this with your debugger to see what is being sent? I notice that you have no error checking in your code so it is quite possible something is failing silently. Are you sure when receiving that your code reads all the data that was sent?
Code-o-mat 1-Nov-13 6:59am    
Did you try saving the gif image you received from your server to a file and then comparing it (e.g. witjh a diff program) to the original to see if they are the same or not? Are you completely sure the gif images are not corrput on the server's machine itself?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900