Re[5]: Нагруженный TCP сервер как и на чем реализовать
От: Аноним  
Дата: 26.02.12 07:36
Оценка:
Здравствуйте, Crackjack, Вы писали:

C>Здравствуйте, maxlosyam, Вы писали:


M>>вот тут http://www.tenouk.com/Module41.html есть пример сервера на select, все делается в одном потоке. просто почитайте поищите про select.

C>Вообще select введен для совместимости с кодами UNIX. Для Win родное — это OVERLAPED, а для улутшения работы с OVERLAPED применяется IOCP.
C>В принципе когда у машины один процессор с одним ядром, то при хорошей реализации однопоточное приложение будет работать быстрее, чем многопоточное. Только реализовать такое приложение сложнее, чем многопоточное. Это я к вопросу о тысячах подключений и по потоку на обработку каждого подключения.

Вы абсолютно правы, потому что данный пример из ссылки, был переделан под винду (с минимальными изменениями) но и это не спасло "отца русской демократии" (с)
Вот к слову код

#include <winsock2.h>
#include <stdio.h>
#include <time.h>
#include <process.h>

#pragma comment(lib,"ws2_32.lib")

/*******select.c*********/

/*******Using select() for I/O multiplexing */


/* port we're listening on */

#define PORT 2020


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

{
    WSADATA lpData;
    /* master file descriptor list */
    fd_set master;
    /* temp file descriptor list for select() */
    fd_set read_fds;
    /* server address */
    struct sockaddr_in serveraddr;
    /* client address */
    struct sockaddr_in clientaddr;

    /* maximum file descriptor number */
    int fdmax;

    /* listening socket descriptor */
    int listener;

    /* newly accept()ed socket descriptor */
    int newfd;

    /* buffer for client data */
    char buf[1024];
    int nbytes;

    /* for setsockopt() SO_REUSEADDR, below */
    int yes = 1;
    int addrlen;
    int i, j;

    /* clear the master and temp sets */

    FD_ZERO(&master);
    FD_ZERO(&read_fds);
    
    WSAStartup(MAKEWORD(2, 2), &lpData);


    /* get the listener */

    if((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        WSACleanup();
        printf("Server-socket() error lol!");
        /*just exit lol!*/
        exit(1);

    }

    printf("Server-socket() is OK...\n");
    /*"address already in use" error message */

    if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (const char *)&yes, sizeof(int)) == -1)
    {
        printf("Server-setsockopt() error lol!");
        exit(1);
    }

    printf("Server-setsockopt() is OK...\n");

    /* bind */
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = INADDR_ANY;
    serveraddr.sin_port = htons(PORT);
    memset(&(serveraddr.sin_zero), '\0', 8);



    if(bind(listener, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1)
    {
        printf("Server-bind() error lol!");
        exit(1);
    }

    printf("Server-bind() is OK...\n");

    /* listen */

    if(listen(listener, 10) == -1)
    {
        printf("Server-listen() error lol!");
        exit(1);

    }

    printf("Server-listen() is OK...\n");

    /* add the listener to the master set */

    FD_SET(listener, &master);
    /* keep track of the biggest file descriptor */
    fdmax = listener; /* so far, it's this one*/

    /* loop */
    for(;;)
    {
        /* copy it */
        read_fds = master;

        if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1)
        {
            printf("Server-select() error lol!");
            exit(1);
        }

        printf("Server-select() is OK...\n");

        /*run through the existing connections looking for data to be read*/
        for(i = 0; i <= fdmax; i++)
        {
            if(FD_ISSET(i, &read_fds))
            { /* we got one... */
                if(i == listener)
                {
                    /* handle new connections */
                    addrlen = sizeof(clientaddr);
                    if((newfd = accept(listener, (struct sockaddr *)&clientaddr, &addrlen)) == -1)
                    {
                        printf("Server-accept() error lol!");
                    }
                    else
                    {
                        printf("Server-accept() is OK...\n");
                        
                        FD_SET(newfd, &master); /* add to master set */

                        if(newfd > fdmax)
                        { /* keep track of the maximum */
                            fdmax = newfd;
                        }
                        printf("%s: New connection from %s on socket %d\n", argv[0], inet_ntoa(clientaddr.sin_addr), newfd);
                    }
                }
                else
                {
                    /* handle data from a client */
                    if((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0)
                    {
                        /* got error or connection closed by client */
                        if(nbytes == 0)
                            /* connection closed */
                            printf("%s: socket %d hung up\n", argv[0], i);
                        else
                            printf("recv() error lol!");

                        /* remove from master set */
                        FD_CLR(i, &master);
                    }
                    else
                    {
                        /* we got some data from a client*/
                        for(j = 0; j <= fdmax; j++)
                        {
                            /* send to everyone! */
                            if(FD_ISSET(j, &master))
                            {
                                /* except the listener and ourselves */
                                if(j != listener && j != i)
                                {
                                    if(send(j, buf, nbytes, 0) == -1)

                                        printf("send() error lol!");
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    WSACleanup();
    return 0;

}
Re[6]: Нагруженный TCP сервер как и на чем реализовать
От: Gomes Россия http://irazin.ru
Дата: 26.02.12 20:03
Оценка:
Я там ниже код давал. Не помогло?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.