socket programming FD_ISSET() method usage

1

so I'm new to socket programming, and I was asked to write the server side that sends data to a client according to a certain request. I'm trying to server multiple clients at the same time. When a client first connects, the server accepts with no troubles whatsoever, but when a client sends a certain request, I get stuck in an infinity loop and it's not clear at all to me why the server keeps sending the same info to the client over and over and over again, below is my code for the server side:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <windows.h>
#include <winsock.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#include <fstream>
#include <vector>
#define MAX_CONNECTION 100
#ifndef max
    #define max(a,b) ((a) < (b) ? (a) : (b))
#endif
typedef struct connection{
    char ipaddr[16];
    int port;
    int sd;
} connection;

static unsigned short SERVER_PORT = 4118;
int main(int argc, char* argv[])
{
    int maxfd =-1;
    fd_set   rset, allset;
    connection client[MAX_CONNECTION];

    int passiveSock; /* Main Server Socket */
    struct sockaddr_in servSock_in;
#ifdef WIN32
    WSADATA wsaData;
    WSAStartup(0x0101, &wsaData);
#endif
    int port;
    if (argc > 1)
        port = atoi(argv[1]);
    else
        port = SERVER_PORT;

    for(int i=0; i < MAX_CONNECTION ; i++)
        client[i].sd = -1;
    memset((char *)&servSock_in, 0, sizeof(servSock_in));
    servSock_in.sin_family = PF_INET;
    servSock_in.sin_addr.s_addr = htonl(INADDR_ANY);
    servSock_in.sin_port = htons((u_short)port);

    passiveSock = socket(PF_INET, SOCK_STREAM, 0);
    if (passiveSock < 0) {
        fprintf(stderr, "I am too tired... I failed to open gate...\n");
        return -1;
    }
    if (bind(passiveSock, (struct sockaddr *)&servSock_in, sizeof(servSock_in)) < 0){
        fprintf(stderr, "I couldn't attach gate to port...\n");
        return -1;
    }
    if (listen(passiveSock, 5) < 0) {
        fprintf(stderr, "I am not hearing anything...\n");
        return -1;
    }

    FD_SET(passiveSock, &allset);
        maxfd = max(maxfd, passiveSock);

        struct sockaddr_in cliSock_in;
        int cliSockLen;
        int connectedSock;
        cliSockLen = sizeof(cliSock_in);
        printf("\n Waiting for an incoming connection at port number %d", port);
        int bytesread = 0;
    for (;;)
    {
        //FD_ZERO(&allset);

        rset = allset;
        int nready = select(maxfd+1,&rset, NULL, NULL, NULL);
        if(FD_ISSET(passiveSock, &rset)){
            printf("In the first if");

            connectedSock = accept(passiveSock, (struct sockaddr *)&cliSock_in, &cliSockLen);
            /* if an error occurs while accepting */
            if (connectedSock == -1)    {
                printf("\n Server: Accept error (errno = %d: %s)\n", errno, strerror(errno));
                continue;
            }




            for (int i=0; i<MAX_CONNECTION; i++)
                if (client[i].sd < 0){
                    client[i].sd=connectedSock;
                    strcpy(client[i].ipaddr, inet_ntoa(cliSock_in.sin_addr));
                    client[i].port= ntohs(cliSock_in.sin_port);
                    printf("\n Server: connection established with %s:%d\n", 
                        client[i].ipaddr, client[i].port);
                    break;
                }
            FD_SET(connectedSock, &allset);
            maxfd = max(maxfd, connectedSock);

        }

        else{
            for(int j = 0 ; j < MAX_CONNECTION; j++){
                connectedSock = client[j].sd;
                printf("connectedSock is %d", connectedSock);
                if(connectedSock < 0)
                    continue;
                if(FD_ISSET(client[j].sd, &rset)){
                    unsigned char buffer[66000];
                    int index = 0;
                    bytesread = recv(connectedSock, (char *)buffer, 66000, 0);
                    int  type;




                    type = (buffer[0] & 0xE0) >> 5;

                    if (type == 0)
                    {
                        char fname[100];
                        int i = 0;
                        int length = (buffer[i++] & 0x1F);
                        memcpy(&fname[0], &buffer[i], length);
                        fname[length] = '\0';
                        i += length;
                        int fs = 0;
                        fs += (buffer[i++] << 8) & 0xff00;
                        fs += buffer[i++];
                        char* filedata = (char*)malloc(fs*sizeof(char));
                        memcpy(&filedata[0], &buffer[i], fs);
                        filedata[fs] = '\0';
                        for (int i = 0; i < fs; i++)
                            printf("%c", filedata[i]);
                        printf("type=%d,length=%d,data=%s,fs=%d,filedata=%s", type, length, fname, fs, filedata);
                        std::ofstream of;
                        of.open(fname, std::ios::binary);
                        for (int i = 0; i < fs; i++)
                            of.write(filedata + i, 1);
                        of.close();
                        unsigned char rep;
                        int reptype = 0;
                        rep = (unsigned char)(reptype & 0x07);
                        send(connectedSock, (char*)(&rep), 1, 0);
                    }
                    else if (type == 1)
                    {
                        char fname[100];
                        int i = 0;
                        int length = (buffer[i++] & 0x1F);
                        memcpy(&fname[0], &buffer[i], length);
                        fname[length] = '\0';
                        i += length;
                        std::ifstream t;
                        int fs;
                        t.open(fname, std::ios::binary);
                        std::vector<char> vec((
                            std::istreambuf_iterator<char>(t)),
                            (std::istreambuf_iterator<char>()));// open input file
                        t.close();
                        fs = vec.size();
                        char* filedata = (char*)malloc(fs*sizeof(char));    // allocate memory for a buffer of appropriate dimension
                        filedata = &vec[0];
                        filedata[fs] = '\0';
                        i = 0;
                        unsigned char* repbuffer = (unsigned char*)malloc(3 + length + fs);
                        repbuffer[i] = (unsigned char)(type & 0x07);
                        repbuffer[i] = repbuffer[i] << 5;
                        repbuffer[i] = repbuffer[i] | (length & 0x0000003F);
                        i++;
                        memcpy(&repbuffer[i], fname, length);
                        i = i + length;
                        printf("sizeof fs=%d", sizeof(fs));
                        repbuffer[i++] = (unsigned char)((fs & 0xff00) >> 8);
                        repbuffer[i++] = (unsigned char)(fs & 0xff);
                        memcpy(&repbuffer[i], filedata, fs);
                        printf("sizeof buffer=%d", sizeof(repbuffer));
                        i = i + fs;
                    //  printf("the buffer contains %s\n",&repbuffer[11]);
                        if (send(connectedSock, (char*)repbuffer, i, 0) == -1)
                        {
                            printf("A local error was detected while sending data! (errno = %d: %s)\n", errno, strerror(errno));
                            return -1;
                        }
                    }   
                    else if (type == 2)
                    {
                        char fname[100],nfname[100];
                        int i = 0;
                        int length = (buffer[i++] & 0x1F);
                        memcpy(&fname[0], &buffer[i], length);
                        fname[length] = '\0';
                        i += length;
                        int nlength = (buffer[i++] & 0x1F);
                        memcpy(&nfname[0], &buffer[i], nlength);
                        nfname[nlength] = '\0';
                        rename(fname,nfname);

                    }
                    else if (type == 3)
                    {
                        char rep[32];
                        strcpy(rep, "bye change get help put");
                        int length = strlen(rep);
                        unsigned char* repbuffer = (unsigned char*)malloc(1 + length);
                        int type = 6;
                        repbuffer[0] = (unsigned char)(type & 0x07);
                        repbuffer[0] = repbuffer[0] << 5;
                        repbuffer[0] = repbuffer[0] | (length & 0x0000003F);
                        memcpy(&repbuffer[1], rep, length);
                        if (send(connectedSock, (char*)repbuffer, length+1, 0) == -1)
                        {
                            perror("A local error was detected while sending data!!");
                            return -1;
                        }
                    }
                    else if (type == 4)
                    {
                        closesocket(connectedSock);
                    }

                    break;
                }
            }
        }
    }   
    closesocket(passiveSock);
    WSACleanup();
    return 0;

}

I feel there's something wrong with the usage of FD_ISSET() method, I've been trying to figure out the error for 2 hours now, pleeassse help

c
sockets
select
asked on Stack Overflow Mar 6, 2015 by sam smith • edited Mar 6, 2015 by Chad

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0