URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 4469
[ Назад ]

Исходное сообщение
"Помогите с сокетами"

Отправлено loewa , 12-Июл-05 07:59 
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <netdb.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define TRUE 2
          /*
           * This program uses select() to check that someone is trying to
           * connect before calling accept().
           */
int msgsock;      
      
void sigalrm(nsig) {
fprintf(stderr,"--> Something wrong and it timeout.\n");
close(msgsock);
           }

      
main()
{
        int sock, length;
        struct sockaddr_in server;
        
        char buf[1024];
        int rval;
        fd_set ready;

        /* Create socket */
        sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock < 0) {
                perror("opening stream socket");
                exit(1);
        }

        /* Name socket using wildcards */
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = INADDR_ANY;
        server.sin_port =ntohs(8891);
        if (bind(sock, (struct sockaddr *)&server, sizeof(server))) {
                perror("binding stream socket");
                exit(1);
        }

        /* Find out assigned port number and print it out */
        length = sizeof(server);
        if (getsockname(sock, (struct sockaddr *)&server, &length)) {
                perror("getting socket name");
                exit(1);
        }
        printf("Socket has port #%d\n", ntohs(server.sin_port));
        struct timeval timeout, rtimeout;
    timeout.tv_sec = 2;
    timeout.tv_usec = 0;
        /* Start accepting connections */
        listen(sock, 5);
        do {    
                FD_ZERO(&ready);
                FD_SET(sock, &ready);
        rtimeout = timeout;
                  if (select(sock + 1, &ready, NULL, NULL, timeout) < 0) {
                        perror("select");
                        return EXIT_FAILURE;
                }
        if (FD_ISSET(sock, &ready)) {
                        msgsock = accept(sock, (struct sockaddr *)0, (int *)0);
            write (msgsock,"Remaind Server#", 15);
                        if (msgsock == -1) {
                                perror("accept");
                                return EXIT_FAILURE;
                                }
                else do
                {
                signal(SIGALRM,sigalrm);    
                    alarm(10);
                                memset(buf, 0, sizeof(buf));
                if ((rval  =  read(msgsock, buf, sizeof(buf))) < 0)
                                        perror("reading stream message");
                                else if (rval == 0)
                                        printf("Ending connection\n");
                                else  
                       alarm(0);    
                       if (! strncmp(buf,"QUIT",4))  
                                            {
                                close(msgsock);
                                }
                    
                                        printf("-->%s", buf);
                    write (msgsock,"Remaind Server#", 15);
                    listen(sock, 100);
                            }
                
            while (rval > 0);
                        close(msgsock);
                } else
                        printf("Do something else\n");          
        
                
        } while (TRUE);
}  

Вопрос:
При одном подключении (telnet localhost 8891) всё работает нормально при втором он ждёт завершения первого подключения, А как сделать одновременную обработку ?


Содержание

Сообщения в этом обсуждении
"Помогите с сокетами"
Отправлено kir , 12-Июл-05 16:40 
организовать пул

"Помогите с сокетами"
Отправлено vnp , 12-Июл-05 21:36 
>Вопрос:
>При одном подключении (telnet localhost 8891) всё работает нормально при втором он
>ждёт завершения первого подключения, А как сделать одновременную обработку ?


Во-первых, переставьте местами write(msgsock, ...) и проверку msgsock == -1

Во вторых, listen нужно делать только один раз.

В третьих, циклы организованы неправильно. Внутренний цикл не нужен. Вместо этого, msgsock надо добавлять к ready, после select анализировать, какие сокеты готовы к обслуживанию, и реагировать соответственно (accept или read). Имейте в виду, что одним msgsock обойтись не удастся -- на каждое подключение понадобится свой.