socket编程FD_ISSET()方法用法

时间:2015-03-06 02:26:45

标签: c sockets select

所以我是套接字编程的新手,我被要求编写服务器端,根据某个请求将数据发送到客户端。我试图同时为多个客户端服务。当客户端第一次连接时,服务器接受没有任何麻烦,但是当客户端发送某个请求时,我陷入无限循环并且它根本不清楚为什么服务器继续发送相同的信息一遍又一遍地对客户端,下面是我的服务器端代码:

#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;

}

我觉得使用FD_ISSET()方法有问题,我现在试图找出错误2小时,请求帮助

0 个答案:

没有答案