套接字仅使用select()

时间:2016-11-20 01:59:48

标签: c sockets select

此程序的服务器会保留一系列故障单号码以及它们是否可用。

客户要求从服务器购买或退票。

我当然不太了解select fx。根据我的判断,您可以将套接字的文件描述符加载到结构中,并选择()检查这些fds是否已准备好读取或写入。这是对的吗?

我需要使用select函数来读取来自2个不同客户端的请求。我认为除了服务器不会在客户端的第二个请求中读取之外,我的工作大部分都在工作。服务器读入第一个客户端请求,处理它并响应,然后挂起,等待下一个请求。

感谢您的帮助,请随时给我任何指示!

服务器代码:

 #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <time.h>
    #include <stdlib.h>

void error(const char *message);
void generateTickets(int ticketArray[][2]);
void parseBuffer(char buffer[], char* request[]);
int sellTicket(int ticketArray[][2], int* refPtr);
int returnTicket(int returnTicketNumber, int ticketArray[][2], int* refPtr);
void printTickets(int ticketArray[][2]);

int main(int argc, char *argv[])
{
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
    int svrSocketFd;//file descriptor for the server side
    int cliSocketFd;//file descriptor fot the client side
    int portNum;//port number
    int readWrite;//holds the return values of the read/write functions

    socklen_t clientLength;//holds the size in bytes of the sockaddr client struct

    char buffer[256];//buffer for reading and writing

    struct sockaddr_in serverAddress;//server struct
    struct sockaddr_in clientAddress;//client struct


    fd_set readfds;
    struct timeval timeout={0,0};
    int selectReturn;

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
    int ticketArray[25][2], returnTicketNumber;//holds ticket nums and whether or not they are avalible (0/1) 
    int ticketsAvalible = 25;//number of tickets avalible
    int *refPtr = &ticketsAvalible;
    char *request[2];//stores parsed client requests
    int i, stringComp, soldTicketNum, clientCheck;

    srand(time(0));//seed random number generator

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

    generateTickets(ticketArray);

    printTickets(ticketArray);


    //check if the correct number of arguments was provided
    if(argc < 2)
    {
        error("ERROR: Port number required\n");
    }

    svrSocketFd = socket(AF_INET, SOCK_STREAM, 0);//creates a socket for the server

    //check that the socket was created
    if(svrSocketFd < 0)
    {
        error("ERROR: Server socket not created\n");
    }

    bzero((char *) &serverAddress, sizeof(serverAddress));//not really sure what this does

    portNum = atoi(argv[1]);//convert passed in port from char to int

    //set the member variables of the server sockaddr struct
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_addr.s_addr = INADDR_ANY;
    serverAddress.sin_port = htons(portNum);

    int on=1;
    setsockopt(svrSocketFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

    //bind the socket to the server struct?
    if(bind(svrSocketFd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0)
    {
        error("ERROR: Unable to bind socket");
    }

    listen(svrSocketFd, 5);

    while(1)
    {   
        do
        {
            FD_ZERO(&readfds);
            FD_SET(svrSocketFd, &readfds);

            selectReturn = select(svrSocketFd + 1, &readfds, NULL, NULL, &timeout);

            if(selectReturn > 0)
            {
                clientLength = sizeof(clientAddress);//returns the size in bytes of the client struct

                cliSocketFd = accept(svrSocketFd, (struct sockaddr *) &clientAddress, &clientLength);

                bzero(buffer, 256);//zeros out the buffer

                readWrite = read(cliSocketFd, buffer, 256);//read data in from the client)

                printf("SERVER IN buffer = %s\n", buffer);

                parseBuffer(buffer, request);//parse buffer and separate into the request array

                stringComp = strcmp(request[0], "BUY");

                if(stringComp == 0)//buy request
                {
                    soldTicketNum = sellTicket(ticketArray, refPtr);

                    bzero(buffer, 256);//zeros out the buffer

                    sprintf(buffer, "%d", soldTicketNum);

                    printf("SERVER OUT buffer = %s\n", buffer);

                    readWrite = write(cliSocketFd, buffer, strlen(buffer));

                }

                stringComp = strcmp(request[0], "RETURN");

                if(stringComp == 0)
                {
                    returnTicketNumber = atoi(request[1]);



                    if(returnTicket(returnTicketNumber, ticketArray, refPtr))
                    {
                        printf("[SERVER]: RETURNED %d\n", returnTicketNumber);
                    }
                    else
                    {
                        printf("[SERVER]: RETURNED %d failed\n", returnTicketNumber);
                    }

                }

            }

        }while(selectReturn > 0);

    }

    printTickets(ticketArray);

    //close the client and server sockets
    close(cliSocketFd);
    close(svrSocketFd);


    return 0;
}
void error(const char *message)
{
    perror(message);
    exit(1);
}

void generateTickets(int ticketArray[][2])
{
    int i;

    for(i = 0; i < 25; i++)
    {
        ticketArray[i][0] = (rand () % 40000 + 10000);
        ticketArray[i][1] = 1;
    }
}

void parseBuffer(char buffer[], char* request[])
{       
    char *token;
    int i = 0;

    token = strtok(buffer, " ");

    while(token != NULL)
    {
        request[i] = token;
        i++;
        token = strtok(NULL, " ");
    }
}

int sellTicket(int ticketArray[][2], int* refPtr)
{
    int i = 0;

    if(*refPtr == 0)
    {
        printf("[SERVER]: No tickets avalible\n");
        return -1;
    }
    else
    {
        //searches for the first avalible ticket and returns the ticket number
        while(ticketArray[i][1] == 0)
        {
            i++;
        }

        (*refPtr)--;//decrement ticketsAvalible

        ticketArray[i][1] = 0;//set ticket as sold (0)

        return ticketArray[i][0];
    }
}

int returnTicket(int returnTicketNumber, int ticketArray[][2], int* refPtr)
{
    int i = 0;



    while(ticketArray[i][0] != returnTicketNumber && i < 25)
    {
        i++;

        if(ticketArray[i][0] == returnTicketNumber && ticketArray[i][1] == 0)
        {
            ticketArray[i][1] = 1;
            (*refPtr)++;
            return 1;
        }
    }

    return 0;


}

void printTickets(int ticketArray[][2])
{
    int i = 0;

    while(i < 25)
    {
        if(ticketArray[i][1] == 0)
        {
            printf("[Ticket # %d] %d : SOLD\n", i, ticketArray[i][0]);
        }
        else
        {
            printf("[Ticket # %d] %d : AVAIL\n", i, ticketArray[i][0]);
        }
        i++;
    }
}

客户代码:

  #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <time.h>
    #include <stdlib.h>

void error(const char *message);
int buyOrReturn();
void buyTicket(char buffer[], int ticketArray[], int* refPtr);
void returnTicket(char buffer[], int ticketArray[], int* refPtr);
void printTickets(int ticketArray[]);

int main(int argc, char *argv[])
{
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
    int cliSocketFd;//hold the file descriptor for the socket
    int portNum;//port number
    int readWrite;//return values for read/write functions

    struct sockaddr_in serverAddress;//server struct containing the address of the server
    struct hostent *server;//defines a host computer on the internet

    char buffer[256];//buffer for reading and writing

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

    int requestNumber = 20;
    int ticketArray[20];//holds ticket nums 
    int ticketsAvalible = 0;//number of tickets avalible
    int *refPtr = &ticketsAvalible;
    int randomNumber;//stores a random number of either a ticket number or decision to buy/sell 
    int i;

    srand(time(0));//seed the random number generator

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------

    for(i = 0; i < 20; i++)
    {
        ticketArray[i] = 0;
    }

    printTickets(ticketArray);

    //check for the correct number of arguments
    if(argc < 3)
    {
        error("ERROR: Need arguments - \"hostname\" \"port number\"\n");
    }

    portNum = atoi(argv[2]);//convertargv string into an int

    cliSocketFd = socket(AF_INET, SOCK_STREAM, 0);//open a socket

    //test is the socket was opened successfully
    if(cliSocketFd < 0)
    {
        error("ERROR: Socket did not open\n");
    }

    server = gethostbyname(argv[1]);//returns a pointer to a host

    //check is the system successfully located the host
    if(server == NULL)
    {
        error("ERROR: No host found\n");
    }

    bzero((char *) &serverAddress, sizeof(serverAddress));//initializes serverAddress to zero

    //set the fields in serverAddress
    serverAddress.sin_family = AF_INET;
    bcopy((char *) server->h_addr, (char *) &serverAddress.sin_addr.s_addr, server->h_length);
    serverAddress.sin_port = htons(portNum);

    //establish and check a connection with the server
    if(connect(cliSocketFd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0)
    {
        error("ERROR: Could not connect to the server\n");
    }

    while(requestNumber != 0)
    {
        printf("REQUEST#: %d\n", requestNumber);
        bzero(buffer, 256);//clears the buffer

    //--------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------

        if(buyOrReturn())//1 buys, 0 returns
        {

            printf("CLIENT: sending buy request\n");
            strcpy(buffer, "BUY ");

            printf("CLIENT OUT buffer = %s\n", buffer);
    //RW
            readWrite = write(cliSocketFd, buffer, strlen(buffer));//send message to the server

            //check if message was not sent
            if(readWrite < 0)
            {
                error("ERROR: Message was not sent\n");
            }

            bzero(buffer, 256);//clears the buffer
    //RW
            readWrite = read(cliSocketFd, buffer, 256);

            printf("CLIENT IN buffer = %s\n", buffer);

            buyTicket(buffer, ticketArray, refPtr);

        }
        else
        {
            printf("CLIENT: sending return request\n");

            returnTicket(buffer, ticketArray, refPtr);  

            printf("CLIENT buffer = %s\n", buffer);

    //RW
            readWrite = write(cliSocketFd, buffer, strlen(buffer));
        }

        requestNumber--;

    }

    printTickets(ticketArray);

    close(cliSocketFd);//close the socket

    return 0;
}

void error(const char *message)
{
    perror(message);
    exit(1);
}

int buyOrReturn()
{

    if((rand() % 4) < 3)
    {
        return 1;//buy
    }
    else
    {
        return 0;//return
    }
}

void buyTicket(char buffer[], int ticketArray[], int* refPtr)
{
    int stringCmp = strcmp(buffer, "-1");

    if(stringCmp != 0)
    {
        ticketArray[*refPtr] = atoi(buffer);

        (*refPtr)++;

        return; 
    }
    else
    {
        return;
    }
}

void returnTicket(char buffer[], int ticketArray[], int* refPtr)
{
    int randomTicketNumber;
    char returnTicketNumber[6];

    if(*refPtr == 0)
    {


        randomTicketNumber = (rand () % 50000 + 49999);

        sprintf(returnTicketNumber, "%d", randomTicketNumber);

        strcpy(buffer, "RETURN ");



        strcat(buffer, returnTicketNumber);

        printf("CLIENT buffer = %s\n", buffer);


        return;
    }
    else
    {
        strcpy(buffer, "RETURN ");

        sprintf(returnTicketNumber, "%d", ticketArray[*refPtr]);

        strcat(buffer, returnTicketNumber);

        (*refPtr)--;//it is assumed that the ticket is valid and returned without error

        return;

    }
}

void printTickets(int ticketArray[])
{
    int i;

    for(i = 0; i < 20; i++)
    {
        printf("[Ticket # %d] %d\n", i, ticketArray[i]);
    }
}

0 个答案:

没有答案