문제

아래 코드를 포함 시켰습니다. 이 프로그램은 포트 8888에서 Telnet 연결을 수락 한 다음 Poll 및 Send and RECV를 사용하여 각 Telnet 클라이언트의 보내기 및 메시지를 보내야하지만 100%작동하지 않습니다. 특정 연결은 항상 누구에게 메시지를 보낼 수 있으며 프로그램은 제대로 작동하지만 메시지를 보낼 수없는 클라이언트는 항상 항상 있습니다. 모든 고객은 항상받을 수 있습니다. (설문 조사는 들어오는 데이터를 등록하지 않습니다)

이 코드는 자체적으로 실행되므로 파일에 넣고 gcc -o app filename.c로 컴파일하면 포트 8888의 LocalHost에 텔넷에 텔넷을 텔넷에 텔넷에 텔넷에 텔넷에 텔넷에 텔넷에 텔넷에 텔넷에 텔넷을 텔넷에 텔넷에 텔넷에 텔넷에 텔넷에 텔넷에 텔넷에 텔넷에 텔넷에 텔넷에 텔넷을 텔넷에 연결하면 작동하지 않습니다. :-(이 코드는 Fedora를 위해 작성되었지만 Linux가 아닌 것이 없어야합니다. 어떤 도움도 실제로 감사 할 것입니다.

#include <stdio.h>
#include <stdlib.h>
#include <poll.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>

#define PORT 8888
#define MAX_CONN 10
#define SECOND 1000
#define TIMEOUT (30 * SECOND)

static int listen_socket();

int main(int argc, char **argv)
{
    struct pollfd **my_fds;                  //array of pollfd structures for poll()
    struct pollfd *curr, *new_conn;          //so I can loop through
    int num_fds;                             //count of how many are being used
    int i, j;                                //for loops
    char buff[255], buff2[255];              //for sending and recieving text
    struct sockaddr_in my_addr, their_addr;  // my address information
    socklen_t sin_size;
    int buff_sz;                             //size of data recieved

    printf("App Started\n");

    //allocate space for 10 
    my_fds = (struct pollfd**) malloc(sizeof(struct pollfd*) * MAX_CONN);

    //set all the pointers to NULL
    for (i = 0; i < MAX_CONN; i++)
        *(my_fds + i) = NULL;

    //I call listen_socket() which creates a socket to listen to
    //this is anchored into my_fds array at element 0.
    curr = (struct pollfd*) malloc (sizeof(struct pollfd));
    curr->fd = listen_socket();
    curr->events = POLLIN;
    curr->revents = 0;

    *my_fds = curr;

    printf("Listening socket fd locked always at position zero in array: %d\n", curr->fd);

    //num_fds, the count of items in the array is set to 1
    //because the listen socket is already present
    num_fds = 1;

    //This is the main loop.
    //While (true)
    //  set all struct pollfd items revents to 0
    //  call poll
    //  loop through, see if there is data to read
    //      read the data
    //          loop through all sockets (except the listen_socket()) and send the data.
    while (1)
    {

        //reset all event flag
        for (i = 1; i < num_fds; i++)
        {
            curr = *(my_fds + i);
            curr->events = POLLIN | POLLPRI;
            printf("%i: fd %i\n", i, curr->fd);
            curr->revents = 0;
            send(curr->fd, "Enter some text:\n", 18, 0);
        }

        //put all this into poll and wait for something magical to happen
        printf("calling poll (%d sockets)\n", num_fds);
        if (poll(*my_fds, num_fds, TIMEOUT) == -1)
        {
            perror("poll");
            exit(0);
        }

        printf("poll returned!\n");

        //First item is the accepting socket....check it independently of the rest!
        curr = *my_fds;
        if (curr->revents != 0)
        {
            printf("We have a new connection.\nAccept goes here...\n");

            //Accept the connection
            sin_size = sizeof their_addr;
            new_conn = (struct pollfd*) malloc(sizeof(struct pollfd));
            new_conn->fd = accept(curr->fd, (struct sockaddr *)&their_addr, &sin_size);
            new_conn->events = POLLIN;
            new_conn->revents = 0;

            printf("Connection from %s\n", inet_ntoa(their_addr.sin_addr));
            sprintf(buff, "Your %i\n", num_fds);
            send(new_conn->fd, buff, 7, 0);

            //Add it to the poll call
            *(my_fds + num_fds) = new_conn;
            num_fds++;

        }
        else
        {
            //skip first one, we know that's the accepting socket (handled above).
            for (i = 1; i < num_fds; i++)
            {
                curr = *(my_fds + i);
                if (curr->revents != 0)
                {
                    buff_sz = recv(curr->fd, &buff, 254, 0);
                    buff[buff_sz] = '\0';
                    printf("Recieved: %s", buff);

                    //send the message to everyone else
                    for (j = 1; j < num_fds; j++)
                    {
                        printf("i = %i, j = %i\n", i, j);
                        if (j != i)
                        {
                            new_conn = *(my_fds + j);
                            sprintf(buff2, "%i sent you %i: %s", i, j, buff);
                            send(new_conn->fd, buff2, strlen(buff2) + 1, 0);
                        }
                    }
                }
            }
        }
    }

    printf("App Ended\n");
}

static int listen_socket()
{
    struct sockaddr_in a;
    int s;
    int yes;

    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket");
        return -1;
    }
    yes = 1;
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
            (char *) &yes, sizeof(yes)) < 0) {
        perror("setsockopt");
        close(s);
        return -1;
    }
    memset(&a, 0, sizeof(a));
    a.sin_port = htons(PORT);
    a.sin_family = AF_INET;
    if (bind(s, (struct sockaddr *) &a, sizeof(a)) < 0) {
        perror("bind");
        close(s);
        return -1;
    }
    printf("Accepting connections on port %d\n", PORT);
    listen(s, 10);
    return s;
}
도움이 되었습니까?

해결책

여론 조사는 다양한 구조물을 가져 가야하지 않습니까? Man Page에서 :

   int poll(struct pollfd fds[], nfds_t nfds, int timeout);

그리고 당신은 구조물에 다양한 포인터를 전달합니다.

struct pollfd **my_fds; 

나는 당신이 가야한다고 생각합니다

struct pollfd *my_fds = calloc(sizeof(pollfd), MAX_CONN); 

그러면 코드가 작동 할 기회가 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top