C语言,多客户端服务器,错误:非套接字上的套接字操作

C语言,多客户端服务器,错误:非套接字上的套接字操作,c,C,我的任务是编写一个服务器程序,它可以接受多个客户端。我正在用C语言编写,并试图用select语句来实现这一点。我能够编译,但每当我telnet进来时,我就会得到一个关于非套接字错误的套接字操作。我试过研究错误,但没有找到太有用的东西。任何协助都将不胜感激 我的服务器的输出是: $ ./assign2 33333 Waiting for connection... fd is 0 EchoServ recv error: Socket operation on non-socket fd is 1

我的任务是编写一个服务器程序,它可以接受多个客户端。我正在用C语言编写,并试图用select语句来实现这一点。我能够编译,但每当我telnet进来时,我就会得到一个关于非套接字错误的套接字操作。我试过研究错误,但没有找到太有用的东西。任何协助都将不胜感激

我的服务器的输出是:

$ ./assign2 33333
Waiting for connection...
fd is 0
EchoServ recv error: Socket operation on non-socket
fd is 1
EchoServ recv error: Socket operation on non-socket
EchoServ recv error: Socket operation on non-socket
telnet的输出为:

$ telnet localhost 33333
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
Welcome to EchoServ chat.
我的服务器代码:

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

#define PORT    50000

main( int argc, char *argv[] )
{
    char                buf[ BUFSIZ ],  /* buffer for incoming data */
                        *endptr,  /*  for strtol()  */
                        *message = "Welcome to EchoServ chat. \r\n"; /* welcome message */
    int                 masterSocket, /* main listening socket for server */
                        newSocket,  /* new sockets for connecting clients */
                        opt = 1,  /* for port reuse code */
                        nBytes,  /* # of incoming bytes */
                        addrlen;
    int                 i,j;  /* temp vars */
    short int           port;  /* port number */
    fd_set              master;  /* master file descriptor list */
    fd_set              temp_fds;  /* temp file descriptor list for select() */
    int                 fdmax;  /* maximum file descriptor number */
    struct sockaddr_in  sin;

    /*  Get port number from the command line, or
        set to default port if no arguments were supplied  */
    if ( argc == 2 ) {
        port = strtol(argv[1], &endptr, 0);
        if ( *endptr ) {
            fprintf(stderr, "EchoServ: Invalid port number.\n");
            exit(EXIT_FAILURE);
        }
    }
    else {
        port = PORT;
    }

    FD_ZERO(&master);    /* clear the master and temp sets */
    FD_ZERO(&temp_fds);

    /* Get an internet domain socket */
    if ( ( masterSocket = socket( AF_INET, SOCK_STREAM, 0) ) == -1 ) {
        perror( "EchoServ socket error" );
        exit( 1 );
    }

    /* Complete the socket structure */
    memset( &sin, 0, sizeof(sin) );
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = INADDR_ANY;
    sin.sin_port = htons(port);

    /* Bind the socket to the port number */
    if ( bind( masterSocket, ( struct sockaddr *) &sin, sizeof( sin ) ) == -1) {
        perror( "EchoServ bind failed" );
        exit( 1 );
    }

    /* Allow port reuse */
    if ( setsockopt( masterSocket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof( opt ) ) == -1 ) { 
        perror( "EchoServ setsockopt error" );
        exit(1);
    } 

    /* Listen for clients that want to connect.         */
    if ( listen( masterSocket, 5 ) == -1 ) {
        perror( "EchoServ listen error" );
        exit( 1 );
    }

    /* add masterSocket to the master set */
    FD_SET(masterSocket, &master);

    /* track largest file descriptor, starting with masterSocket */
    fdmax = masterSocket;


    /* Wait for a client connection, then accept it. */

    puts ( "Waiting for connection..." );
    while(1){
        temp_fds = master;  /* copy master set to temp set */
        //addrlen = sizeof(sin); 
        /* wait for activity on a socket */
        if (select(fdmax+1, &temp_fds, NULL, NULL, NULL) == -1) {
            perror("EchoServ select error");
            exit(1);
        }

        for ( i = 0; i <= fdmax; i++ ){
            printf("fd is %d\n", i);  /*debug*/
            if ( FD_ISSET( i, &temp_fds ) ){  /* true if file descriptor is in set */

                /* accept new connection */               
                if ( i == masterSocket ){
                    addrlen = sizeof( sin );  
                    if ( (newSocket = accept( masterSocket, ( struct sockaddr *) &sin, &addrlen )) == -1 )
                        perror("EchoServ:  accept error");
                    else {
                        printf("New connection accepted\n"); /*debug*/
                        FD_SET( newSocket, &master ); /* add new connection to master set */
                        if ( newSocket > fdmax )  /* update max descriptor */
                            fdmax = newSocket;
                        //print details of new connection
                        printf("New connection on %s:%d, socket fd is %d \n", 
                        inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), newSocket );

                        //send new connection greeting message
                        if( send( newSocket, message, strlen( message ), 0) == -1 )
                        {
                             perror("EchoServ welcome message error");
                        }
                        puts("Welcome message sent successfully");
                    }
                }
            }

            /* handle incoming data */
            else{
                if ( ( nBytes = recv( i, buf, sizeof( buf ), 0 ) ) <= 0 ){ /* error or closed connection */
                    if ( nBytes == 0 )  /* connection closed */
                        printf( "EchoServ: socket %d closed by client\n", i );
                    else /* recv error */
                        perror("EchoServ recv error");
                    close( i );  /* close socket */
                    FD_CLR( i, &master );  /* remove from master set */
                }
                else { /* got some data */ 
                    for( j = 0; j <= fdmax; j++ ){
                        if ( FD_ISSET( j, &master ) ){  /* send data to all sockets */
                            if( j != i && j != masterSocket ){  /* except self and masterSocket */
                                if ( send( j, buf, nBytes, 0) == -1)
                                    perror("EchoServ send error");
                            }  
                        }
                    }
                }
            }
        }
    }

    return( 0 );
}
感谢您的帮助。

因此,您可以测试FD_ISSETi和temp_fds,并在else分支上尝试在i上接收。所以,基本上,你只是在尝试接收,如果我是无效的或会阻止


当然,这一切都源于对块和支撑的无限使用。如果i==masterSocket,您可能想与其他代码配对。

我很好奇:您是从哪里获得这种编码风格的?您是对的。我把else和错误的if联系起来了。括号太多:P现在我可以连接了,但是数据没有在客户端之间传递。找出了数据没有传递的原因。我缺少一组父项:if nBytes=recv I,buf,sizeof buf,0