2

Linux でネットワーク プログラミングをしようとしましたが、また行き詰まったようです。select() 関数の最初の引数を取得していないようです。filedescriptor + 1私の知る限り、これは最後に作られたソケットのはずです。ほとんどの最高値filedescriptorには数字の 6 が含まれています。 に を追加するfiledescriptorと、fd_set突然 64 に変わりますfd_bytes。したがって、6 + 1 はブロックし続けるため、select ステートメントには適していないようですが、fd_bytesから取得した場合はそうではありませんfd_set。私はこれらすべてについて非常に混乱しており、この件についてアドバイスをしたいと思います。または、誰かがそれを持っていれば、物事を簡単にすることができる sigio の良いチュートリアルです。

サーバー.cpp

#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 <boost/thread/thread.hpp>
#include <sys/time.h>
#include <sys/ioctl.h>

using namespace std;

void error(char *msg,int socket)
{
    perror(msg);
    close(socket);
    exit(1);
}

int main(int argc, char** argv) {
    int sockfd, newsockfd, portno, n;
    socklen_t clilen;
    fd_set readfds;
    FD_ZERO(&readfds);
/*
 * Sockfd, newsockfd contain values returned by the socket
 * portno stores the port number on which the server accepts connections
 * clilen stores the size of the address of the client
 * n contains the amount of character written of read
 */
    char buffer[256];
    /* buffer contains the characters read from the socket*/

    struct sockaddr_in serv_addr, cli_addr;
    /* 
     * sockaddr_in contains an internet address
     * serv_addr contains the servers address
     * cli addr contains the clients address
     */
    if(argc < 2)
    {
        fprintf(stderr,"ERROR no port provided");
       exit(1);
    }
    /*
     * error if no argument
     */
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    int opt = 1;
    ioctl(sockfd, FIONBIO, &opt);

    if(sockfd < 0){
        error("ERROR opening socket", sockfd);
    }    
    /*
     * socket() creates a new socket
     * argument 1 contains the address domain
     * argument 2 contains the socket type
     * argument 3 contains the protocol should be 0
     * socket() returns a reference for itself
     */
    bzero((char*) &serv_addr, sizeof(serv_addr));
    /* empty the serv_addr variable*/
    portno = atoi(argv[1]);
    /*converts the port argument from string  to int*/
    serv_addr.sin_family = AF_INET;
    /*set the code for the address family*/
    serv_addr.sin_port = htons(portno);
    /*htons converts the portno to network bytes and gives it to the server address*/
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    /*set the server ip to the ip of the running machine*/
    if(bind(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
        error("ERROR on binding", sockfd);
    /*
     * bind() binds a socket to an address, in this case the
     * addess of the current host
     */
    listen(sockfd,5);
    /*the listen system call allows the process to listen on the socket for 
    connections*/
    clilen = sizeof(cli_addr);
    do{
    newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
    }while(newsockfd < 0);
    /*
     * accept() lets the system wait until a client connects to the server
     */
    FD_SET(newsockfd,&readfds);
    int sockcount = pselect(readfds.fds_bits[0] + 1,&readfds,NULL,NULL,NULL,NULL);

    bzero(buffer,256);
    n = read(newsockfd,buffer,255);
    if(n < 0) error("ERROR reading from socket", sockfd);
    printf("Here is the message: %s", buffer);
    /*
     * bzero empties the buffer
     * read obviously reads data from the new socket descriptor
     */
    n = write(newsockfd,"I got your message",18);
    if(n < 0) error("ERROR writing to socket", sockfd);

    close(sockfd);
    return 0;
}

一部 (またはすべて) のコードは意味をなさないかもしれませんが、それは主に、コードの動作をテストし、その後マルチスレッドにするためです。上記のコードは、それほど機能しません。telnet またはhttp://www.linuxhowtos.org/C_C++/socket.htmにあるチュートリアルのクライアントでテストできます。

4

2 に答える 2

1

私はこれまで誰にも種を蒔いたことがありませんreadfds.fds_bits[0] + 1。あなたの場合、で使用することができnewsockfd + 1ますpselect()

于 2012-10-24T14:51:04.537 に答える
1

pselectのドキュメントによると、コードで発生しているtimespec引数を指定しないと、ブロックされます。これに関係なく、pselectへの呼び出しは、a)pselectへの呼び出しの結果に基づいて決定を下さず、b)直後にrecvを呼び出すため、実際には何の役にも立ちません。これはブロッキング呼び出しです。

于 2012-10-24T14:51:12.930 に答える