Обеспечение работы асинхронного сервера сокетов и клиента (написано на C) - PullRequest
1 голос
/ 18 февраля 2010

Не могли бы вы помочь мне с этими кодами?Я пытаюсь заставить клиента и сервер общаться асинхронно.Я имею в виду, что и клиент, и сервер не ждут друг друга (например, когда сервер или клиент читает из recvfrom (), а данные отсутствуют, он принимает последний полученный (то, что я назвал, резервное копирование). Вот коды:

клиент

    ...

    /* Create a datagram/UDP socket */
    if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
        DieWithError("socket() failed");

    /* Construct the server address structure */
    memset(&echoServAddr, 0, sizeof(echoServAddr));    /* Zero out structure */
    echoServAddr.sin_family = AF_INET;                 /* Internet addr family */
    echoServAddr.sin_addr.s_addr = inet_addr(servIP);  /* Server IP address */
    echoServAddr.sin_port   = htons(echoServPort);     /* Server port */

    /* Set signal handler for SIGIO */
    handler.sa_handler = SIGIOHandler;
    /* Create mask that mask all signals */
    if (sigfillset(&handler.sa_mask) < 0) 
        DieWithError("sigfillset() failed");
    /* No flags */
    handler.sa_flags = 0;

    if (sigaction(SIGIO, &handler, 0) < 0)
        DieWithError("sigaction() failed for SIGIO");

    /* We must own the socket to receive the SIGIO message */
    if (fcntl(sock, F_SETOWN, getpid()) < 0)
        DieWithError("Unable to set process owner to us");

    /* Arrange for nonblocking I/O and SIGIO delivery */
    if (fcntl(sock, F_SETFL, O_NONBLOCK | FASYNC) < 0)
        DieWithError("Unable to put server sock into non-blocking");
...

сервер ...

    /* Create socket for sending/receiving datagrams */
    if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
        DieWithError("socket() failed");

    /* Set up the server address structure */
    memset(&echoServAddr, 0, sizeof(echoServAddr));   /* Zero out structure */
    echoServAddr.sin_family = AF_INET;                /* Internet family */
    echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interf*/
    echoServAddr.sin_port = htons(echoServPort);      /* Port */

    /* Bind to the local address */
    if (bind(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
        DieWithError("bind() failed");

    /* Set signal handler for SIGIO */
    handler.sa_handler = SIGIOHandler;
    /* Create mask that mask all signals */
    if (sigfillset(&handler.sa_mask) < 0) 
        DieWithError("sigfillset() failed");
    /* No flags */
    handler.sa_flags = 0;

    if (sigaction(SIGIO, &handler, 0) < 0)
        DieWithError("sigaction() failed for SIGIO");

    if (fcntl(sock, F_SETOWN, getpid()) < 0)
        DieWithError("Unable to set process owner to us");

    /* Arrange for nonblocking I/O and SIGIO delivery */
    if (fcntl(sock, F_SETFL, O_NONBLOCK | FASYNC) < 0)
        DieWithError("Unable to put client sock into non-blocking");
 ...

Коды скомпилированы и связаны с любой проблемой, но они не обмениваются данными друг с другом, почему? ... есть где-то проблема?

Спасибо за ваши ответы,

PS: коды теперь удалены ...

Ответы [ 2 ]

1 голос
/ 18 февраля 2010

Проверьте ваш порт, я думаю, что они исчерпаны ... должно быть 65535, что является максимумом для номера порта (16 бит)!

Дайте ему меньшее число, и с вами все будет в порядке!

Редактировать: Максимальное количество используемых портов - 65536, что составляет максимум 16 битов, поскольку это короткое целое число. Если вы превысите максимум, он потерпит неудачу. Дайте и клиенту, и серверу произвольный номер порта, который больше 1024 и меньше 65536.

Взгляните на Руководство Биджа по программированию сокетов ...

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

0 голосов
/ 18 февраля 2010

Во время вашего recv вы можете использовать MSG_PEEK | MSG_DONTWAIT как опции для recv, которые позволят вам просто проверить, есть ли какие-либо данные, которые необходимо прочитать.

...