Помогите написать асинхронный сокет на c++

Тема в разделе "ASM, С/С++, Delphi, Java", создана пользователем Volukrem, 27 май 2016.

  1. Volukrem

    Volukrem Создатель

    Регистр.:
    8 мар 2016
    Сообщения:
    46
    Симпатии:
    5
    Может быть есть у кого работающий пример асинхронного сокета? В частности нужен рабочий клиент.
     
  2. twaego

    twaego Создатель

    Регистр.:
    13 авг 2016
    Сообщения:
    2
    Симпатии:
    4
  3. fliuger

    fliuger Создатель

    Регистр.:
    24 янв 2017
    Сообщения:
    11
    Симпатии:
    4
  4. Akillon

    Akillon Создатель

    Регистр.:
    23 янв 2017
    Сообщения:
    17
    Симпатии:
    2
  5. radder8

    radder8 Писатель

    Регистр.:
    11 май 2017
    Сообщения:
    6
    Симпатии:
    1
    #include <Перейти по ссылке>
    #include <Перейти по ссылке>
    #include <Перейти по ссылке>
    #include <Перейти по ссылке>
    #include <Перейти по ссылке>
    #include <Перейти по ссылке>
    #include <Перейти по ссылке>
    #include <Перейти по ссылке>
    #include <Перейти по ссылке>
    #include <Перейти по ссылке>
    #include <Перейти по ссылке>

    static int forward_port;

    #undef max
    #define max(x,y) ((x) > (y) ? (x) : (y))

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

    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    return -1;
    }
    yes = 1;
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
    &yes, sizeof(yes)) == -1) {
    perror("setsockopt");
    close(s);
    return -1;
    }
    memset(&a, 0, sizeof(a));
    a.sin_port = htons(listen_port);
    a.sin_family = AF_INET;
    if (bind(s, (struct sockaddr *) &a, sizeof(a)) == -1) {
    perror("bind");
    close(s);
    return -1;
    }
    printf("accepting connections on port %d\n", listen_port);
    listen(s, 10);
    return s;
    }

    static int
    connect_socket(int connect_port, char *address)
    {
    struct sockaddr_in a;
    int s;

    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    close(s);
    return -1;
    }

    memset(&a, 0, sizeof(a));
    a.sin_port = htons(connect_port);
    a.sin_family = AF_INET;

    if (!inet_aton(address, (struct in_addr *) &a.sin_addr.s_addr)) {
    perror("bad IP address format");
    close(s);
    return -1;
    }

    if (connect(s, (struct sockaddr *) &a, sizeof(a)) == -1) {
    perror("connect()");
    shutdown(s, SHUT_RDWR);
    close(s);
    return -1;
    }
    return s;
    }

    #define SHUT_FD1 do { \
    if (fd1 >= 0) { \
    shutdown(fd1, SHUT_RDWR); \
    close(fd1); \
    fd1 = -1; \
    } \
    } while (0)

    #define SHUT_FD2 do { \
    if (fd2 >= 0) { \
    shutdown(fd2, SHUT_RDWR); \
    close(fd2); \
    fd2 = -1; \
    } \
    } while (0)

    #define BUF_SIZE 1024

    int
    main(int argc, char *argv[])
    {
    int h;
    int fd1 = -1, fd2 = -1;
    char buf1[BUF_SIZE], buf2[BUF_SIZE];
    int buf1_avail, buf1_written;
    int buf2_avail, buf2_written;

    if (argc != 4) {
    fprintf(stderr, "Usage\n\tfwd <listen-port> "
    "<forward-to-port> <forward-to-ip-address>\n");
    exit(EXIT_FAILURE);
    }

    signal(SIGPIPE, SIG_IGN);

    forward_port = atoi(argv[2]);

    h = listen_socket(atoi(argv[1]));
    if (h == -1)
    exit(EXIT_FAILURE);

    for (;;) {
    int r, nfds = 0;
    fd_set rd, wr, er;

    FD_ZERO(&rd);
    FD_ZERO(&wr);
    FD_ZERO(&er);
    FD_SET(h, &rd);
    nfds = max(nfds, h);
    if (fd1 > 0 && buf1_avail < BUF_SIZE) {
    FD_SET(fd1, &rd);
    nfds = max(nfds, fd1);
    }
    if (fd2 > 0 && buf2_avail < BUF_SIZE) {
    FD_SET(fd2, &rd);
    nfds = max(nfds, fd2);
    }
    if (fd1 > 0 && buf2_avail - buf2_written > 0) {
    FD_SET(fd1, &wr);
    nfds = max(nfds, fd1);
    }
    if (fd2 > 0 && buf1_avail - buf1_written > 0) {
    FD_SET(fd2, &wr);
    nfds = max(nfds, fd2);
    }
    if (fd1 > 0) {
    FD_SET(fd1, &er);
    nfds = max(nfds, fd1);
    }
    if (fd2 > 0) {
    FD_SET(fd2, &er);
    nfds = max(nfds, fd2);
    }

    r = select(nfds + 1, &rd, &wr, &er, NULL);

    if (r == -1 && errno == EINTR)
    continue;

    if (r == -1) {
    perror("select()");
    exit(EXIT_FAILURE);
    }

    if (FD_ISSET(h, &rd)) {
    unsigned int l;
    struct sockaddr_in client_address;

    memset(&client_address, 0, l = sizeof(client_address));
    r = accept(h, (struct sockaddr *) &client_address, &l);
    if (r == -1) {
    perror("accept()");
    } else {
    SHUT_FD1;
    SHUT_FD2;
    buf1_avail = buf1_written = 0;
    buf2_avail = buf2_written = 0;
    fd1 = r;
    fd2 = connect_socket(forward_port, argv[3]);
    if (fd2 == -1)
    SHUT_FD1;
    else
    printf("connect from %s\n",
    inet_ntoa(client_address.sin_addr));
    }
    }

    /* NB: read oob data before normal reads */

    if (fd1 > 0)
    if (FD_ISSET(fd1, &er)) {
    char c;

    r = recv(fd1, &c, 1, MSG_OOB);
    if (r < 1)
    SHUT_FD1;
    else
    send(fd2, &c, 1, MSG_OOB);
    }
    if (fd2 > 0)
    if (FD_ISSET(fd2, &er)) {
    char c;

    r = recv(fd2, &c, 1, MSG_OOB);
    if (r < 1)
    SHUT_FD2;
    else
    send(fd1, &c, 1, MSG_OOB);
    }
    if (fd1 > 0)
    if (FD_ISSET(fd1, &rd)) {
    r = read(fd1, buf1 + buf1_avail,
    BUF_SIZE - buf1_avail);
    if (r < 1)
    SHUT_FD1;
    else
    buf1_avail += r;
    }
    if (fd2 > 0)
    if (FD_ISSET(fd2, &rd)) {
    r = read(fd2, buf2 + buf2_avail,
    BUF_SIZE - buf2_avail);
    if (r < 1)
    SHUT_FD2;
    else
    buf2_avail += r;
    }
    if (fd1 > 0)
    if (FD_ISSET(fd1, &wr)) {
    r = write(fd1, buf2 + buf2_written,
    buf2_avail - buf2_written);
    if (r < 1)
    SHUT_FD1;
    else
    buf2_written += r;
    }
    if (fd2 > 0)
    if (FD_ISSET(fd2, &wr)) {
    r = write(fd2, buf1 + buf1_written,
    buf1_avail - buf1_written);
    if (r < 1)
    SHUT_FD2;
    else
    buf1_written += r;
    }

    /* check if write data has caught read data */

    if (buf1_written == buf1_avail)
    buf1_written = buf1_avail = 0;
    if (buf2_written == buf2_avail)
    buf2_written = buf2_avail = 0;

    /* one side has closed the connection, keep
    writing to the other side until empty */

    if (fd1 < 0 && buf1_avail - buf1_written == 0)
    SHUT_FD2;
    if (fd2 < 0 && buf2_avail - buf2_written == 0)
    SHUT_FD1;
    }
    exit(EXIT_SUCCESS);
    }
     
  6. dkann

    dkann Создатель

    Регистр.:
    22 июл 2009
    Сообщения:
    15
    Симпатии:
    1
    есть туториал с нереальной крутой и мощной библиотекой QT, в том числе и клиент Перейти по ссылке