Главная страница
Навигация по странице:

  • Проверка работоспособности TCP сервера

  • Проверка работоспособности TCP клиента

  • Проверка работоспособности UDP сервера и клиента

  • // Шаг 2 создание сокета

  • // Шаг 3 связывание сокета с локальным адресом

  • // Шаг 4 ожидание подключений

  • // Шаг 5 извлекаем сообщение из очереди

  • // Шаг 1 инициализация библиотеки Winsock if (WSAStartup(0x202,(WSADATA *)buff[0])){printf("WSAStart error %d\n",WSAGetLastError());return 1;}// Шаг 2 создание сокета

  • // Шаг 3 установка соединения

  • // Шаг 4 чтение и передача сообщений

  • // Шаг 1 подключение библиотеки if (WSAStartup(0x202,(WSADATA *) buff[0])){printf("WSAStartup error: %d\n",WSAGetLastError());return 1;}// Шаг 2 создание сокета

  • // Шаг 4 обработка пакетов, присланных клиентами

  • // Определяем IP адрес клиента и прочие атрибуты

  • S:%s\n",buff[0]);//_посылка_датаграммы_клиенту">// Вывод на экран printf("C=>S:%s\n",buff[0]);// посылка датаграммы клиенту

  • // Шаг 1 иницилизация библиотеки Winsocks if (WSAStartup(0x202,(WSADATA *)buff[0])){printf("WSAStartup error: %d\n",WSAGetLastError());return 1;}// Шаг 2 открытие сокета

  • // Шаг 3 обмен сообщений с сервером

  • Крисс Касперски - Самоучитель игры на winsock. ВведениеСокеты


    Скачать 188.88 Kb.
    НазваниеВведениеСокеты
    Дата19.03.2018
    Размер188.88 Kb.
    Формат файлаpdf
    Имя файлаКрисс Касперски - Самоучитель игры на winsock.pdf
    ТипДокументы
    #38819
    страница3 из 3
    1   2   3
    Законченные реализации
    Ниже приведено четыре подробно комментированных исходных текста, реа лизующих простых TCP и UDP эхо сервера и TCP и UDP клиентов. (Эхо сервер просто возвращает клиенту, полученные от него данные).
    Для их компиляции с помощью Microsoft Visual C++ достаточно отдать команду: "cl.exe имя_файла.cpp ws2_32.lib".
    Проверка работоспособности TCP сервера: запустите TCP сервер и наберите в командной строке Windows "telnet.exe 127.0.0.1 666", где 127.0.0.1 обозначает локальный адрес вашего узла (это специально зарезервированный для этой цели адрес и он выглядит одинаково для всех узлов), а 666 – номер порта на который
    Крис Касперски
    1 14 4
    С
    Са
    ам
    мо
    оууч
    чи
    итте
    ел
    ль
    ь и
    иггр
    ры
    ы н
    на
    а W
    WIIN
    NS
    SO
    OC
    CK
    K

    "сел" сервер. Если все работает успешно, то telnet установит соединение и на экра не появится приветствие "Hello, Sailor!". Теперь можно набирать на клавиатуре некоторый текст и получать его назад от сервера.
    Проверка работоспособности TCP клиента: запустите TCP сервер и затем одну или несколько копий клиента. В каждом из них можно набирать некоторый текст на клавиатуре и после нажатия на Enter получать его обратно от сервера.
    Проверка работоспособности UDP сервера и клиента: запустите UDP сервер и одну или несколько копий клиента – в каждой из них можно набирать на клавиа туре некоторые данные и получать их обратно от сервера.
    Внимание: работая с серверными приложениями, вы (если не предпримите
    дополнительных мер) предоставляете возможность воспользоваться ими
    каждому абоненту Интернет (если в момент работы сервера вы подключены
    к Интернет). Проблема в том, что ошибки реализации, в особенности перепол
    няющиеся буфера, могут позволить удаленному злоумышленнику выполнить на
    вашей машине любой код, со всеми вытекающими от сюда последствиями.
    Будьте очень внимательны, а еще лучше, не входите в Интернет, пока не
    будете полностью уверенны, что сервера отлажены и не содержат ошибок!
    Пример реализации TCP эхо сервера
    // Пример простого TCP эхо сервера
    #include
    #include
    // Wincosk2.h должен быть раньше windows!
    #include
    #define MY_PORT
    666
    // Порт, который слушает сервер
    // макрос для печати количества активных пользователей
    #define PRINTNUSERS if (nclients) printf("%d user on line\n",nclients);else printf("No User on line\n");
    // прототип функции, обслуживающий подключившихся пользователей
    DWORD WINAPI SexToClient(LPVOID client_socket);
    // глобальная переменная – количество активных пользователей int nclients = 0;
    int main(int argc, char* argv[])
    {
    char buff[1024];
    // Буфер для различных нужд printf("TCP SERVER DEMO\n");
    // Шаг 1 Инициализация Библиотеки Сокетов
    // Т. к. возвращенная функцией информация не используется
    // ей передается указатель на рабочий буфер, преобразуемый к указателю
    // на структуру WSADATA.
    // Такой прием позволяет сэкономить одну переменную, однако, буфер
    // должен быть не менее полкилобайта размером (структура WSADATA
    // занимает 400 байт)
    Крис Касперски
    1 15 5
    С
    Са
    ам
    мо
    оууч
    чи
    итте
    ел
    ль
    ь и
    иггр
    ры
    ы н
    на
    а W
    WIIN
    NS
    SO
    OC
    CK
    K
    if (WSAStartup(0x0202,(WSADATA *) &buff[0]))
    {
    // Ошибка!
    printf("Error WSAStartup %d\n",WSAGetLastError());
    return 1;
    }
    // Шаг 2 создание сокета
    SOCKET mysocket;
    // AF_INET сокет Интернета
    // SOCK_STREAM
    потоковый сокет (с установкой соединения)
    // 0
    по умолчанию выбирается TCP протокол if ((mysocket=socket(AF_INET,SOCK_STREAM,0))<0)
    {
    // Ошибка!
    printf("Error socket %d\n",WSAGetLastError());
    WSACleanup();
    // Деиницилизация библиотеки Winsock return 1;
    }
    // Шаг 3 связывание сокета с локальным адресом
    sockaddr_in local_addr;
    local_addr.sin_family=AF_INET;
    local_addr.sin_port=htons(MY_PORT);
    // не забываем о сетевом порядке!!!
    local_addr.sin_addr.s_addr=0;
    // сервер принимаем подключения
    // на все свои IP адреса
    // вызываем bind для связывания if (bind(mysocket,(sockaddr *) &local_addr, sizeof(local_addr)))
    {
    // Ошибка printf("Error bind %d\n",WSAGetLastError());
    closesocket(mysocket);
    // закрываем сокет!
    WSACleanup();
    return 1;
    }
    // Шаг 4 ожидание подключений
    // размер очереди – 0x100
    if (listen(mysocket, 0x100))
    {
    // Ошибка printf("Error listen %d\n",WSAGetLastError());
    closesocket(mysocket);
    WSACleanup();
    return 1;
    }
    printf("Ожидание подключений…\n");
    // Шаг 5 извлекаем сообщение из очереди
    SOCKET client_socket;
    // сокет для клиента sockaddr_in client_addr;
    // адрес клиента (заполняется системой)
    Крис Касперски
    1 16 6
    С
    Са
    ам
    мо
    оууч
    чи
    итте
    ел
    ль
    ь и
    иггр
    ры
    ы н
    на
    а W
    WIIN
    NS
    SO
    OC
    CK
    K

    // функции accept необходимо передать размер структуры int client_addr_size=sizeof(client_addr);
    // цикл извлечения запросов на подключение из очереди while((client_socket=accept(mysocket, (sockaddr *) &client_addr, &client_addr_size)))
    {
    nclients++;
    // увеличиваем счетчик подключившихся клиентов
    // пытаемся получить имя хоста
    HOSTENT *hst;
    hst=gethostbyaddr((char *) &client_addr.sin_addr.s_addr,4,AF_INET);
    // вывод сведений о клиенте printf("+%s [%s] new connect!\n",
    (hst)?hst >h_name:"",inet_ntoa(client_addr.sin_addr));
    PRINTNUSERS
    // Вызов нового потока для обслужвания клиента
    // Да, для этого рекомендуется использовать _beginthreadex
    // но, поскольку никаких вызов функций стандартной Си библиотеки
    // поток не делает, можно обойтись и CreateThread
    DWORD thID;
    CreateThread(NULL,NULL,SexToClient,&client_socket,NULL,&thID);
    }
    return 0;
    }
    // Эта функция создается в отдельном потоке
    // и обсуживает очередного подключившегося клиента независимо от остальных
    DWORD WINAPI SexToClient(LPVOID client_socket)
    {
    SOCKET my_sock;
    my_sock=((SOCKET *) client_socket)[0];
    char buff[20*1024];
    #define sHELLO "Hello, Sailor\r\n"
    // отправляем клиенту приветствие send(my_sock,sHELLO,sizeof(sHELLO),0);
    // цикл эхо сервера: прием строки от клиента и возвращение ее клиенту while( (int bytes_recv=recv(my_sock,&buff[0],sizeof(buff),0)) &&
    bytes_recv !=SOCKET_ERROR)
    send(my_sock,&buff[0],bytes_recv,0);
    // если мы здесь, то произошел выход из цикла по причине
    // возращения функцией recv ошибки – соединение с клиентом разорвано nclients
    ;
    // уменьшаем счетчик активных клиентов printf(" disconnect\n"); PRINTNUSERS
    // закрываем сокет closesocket(my_sock);
    return 0;
    }
    Крис Касперски
    1 17 7
    С
    Са
    ам
    мо
    оууч
    чи
    итте
    ел
    ль
    ь и
    иггр
    ры
    ы н
    на
    а W
    WIIN
    NS
    SO
    OC
    CK
    K

    Пример реализации TCP клиента
    // Пример простого TCP клиента
    #include
    #include
    #include
    #include
    #define PORT 666
    #define SERVERADDR "127.0.0.1"
    int main(int argc, char* argv[])
    {
    char buff[1024];
    printf("TCP DEMO CLIENT\n");
    // Шаг 1 инициализация библиотеки Winsock
    if (WSAStartup(0x202,(WSADATA *)&buff[0]))
    {
    printf("WSAStart error %d\n",WSAGetLastError());
    return 1;
    }
    // Шаг 2 создание сокета
    SOCKET my_sock;
    my_sock=socket(AF_INET,SOCK_STREAM,0);
    if (my_sock<0)
    {
    printf("Socket() error %d\n",WSAGetLastError());
    return 1;
    }
    // Шаг 3 установка соединения
    // заполнение структуры sockaddr_in – указание адреса и порта сервера sockaddr_in dest_addr;
    dest_addr.sin_family=AF_INET;
    dest_addr.sin_port=htons(PORT);
    HOSTENT *hst;
    // преобразование IP адреса из символьного в сетевой формат if (inet_addr(SERVERADDR)!=INADDR_NONE)
    dest_addr.sin_addr.s_addr=inet_addr(SERVERADDR);
    else
    // попытка получить IP адрес по доменному имени сервера if (hst=gethostbyname(SERVERADDR))
    // hst >h_addr_list содержит не массив адресов,
    // а массив указателей на адреса
    ((unsigned long *)&dest_addr.sin_addr)[0]=
    ((unsigned long **)hst >h_addr_list)[0][0];
    else
    {
    printf("Invalid address %s\n",SERVERADDR);
    closesocket(my_sock);
    WSACleanup();
    return 1;
    }
    Крис Касперски
    1 18 8
    С
    Са
    ам
    мо
    оууч
    чи
    итте
    ел
    ль
    ь и
    иггр
    ры
    ы н
    на
    а W
    WIIN
    NS
    SO
    OC
    CK
    K

    // адрес сервера получен – пытаемся установить соединение if (connect(my_sock,(sockaddr *)&dest_addr,sizeof(dest_addr)))
    {
    printf("Connect error %d\n",WSAGetLastError());
    return 1;
    }
    printf("Соединение с %s успешно установлено\n\
    Type quit for quit\n\n",SERVERADDR);
    // Шаг 4 чтение и передача сообщений
    int nsize;
    while((nsize=recv(my_sock,&buff[0],sizeof(buff) 1,0))!=SOCKET_ERROR)
    {
    // ставим завершающий ноль в конце строки buff[nsize]=0;
    // выводим на экран printf("S=>C:%s",buff);
    // читаем пользовательский ввод с клавиатуры printf("S<=C:"); fgets(&buff[0],sizeof(buff) 1,stdin);
    // проверка на "quit"
    if (!strcmp(&buff[0],"quit\n"))
    {
    // Корректный выход printf("Exit...");
    closesocket(my_sock);
    WSACleanup();
    return 0;
    }
    // передаем строку клиента серверу send(my_sock,&buff[0],nsize,0);
    }
    printf("Recv error %d\n",WSAGetLastError());
    closesocket(my_sock);
    WSACleanup();
    return 1;
    }
    Пример реализации UDP сервера
    // Пример простого UDP эхо сервера
    #include
    #include
    #define PORT 666
    // порт сервера
    #define sHELLO "Hello, %s [%s] Sailor\n"
    Крис Касперски
    1 19 9
    С
    Са
    ам
    мо
    оууч
    чи
    итте
    ел
    ль
    ь и
    иггр
    ры
    ы н
    на
    а W
    WIIN
    NS
    SO
    OC
    CK
    K
    int main(int argc, char* argv[])
    {
    char buff[1024];
    printf("UDP DEMO echo Server\n");
    // Шаг 1 подключение библиотеки
    if (WSAStartup(0x202,(WSADATA *) &buff[0]))
    {
    printf("WSAStartup error: %d\n",WSAGetLastError());
    return 1;
    }
    // Шаг 2 создание сокета
    SOCKET my_sock;
    my_sock=socket(AF_INET,SOCK_DGRAM,0);
    if (my_sock==INVALID_SOCKET)
    {
    printf("Socket() error: %d\n",WSAGetLastError());
    WSACleanup();
    return 1;
    }
    // Шаг 3 связывание сокета с локальным адресом
    sockaddr_in local_addr;
    local_addr.sin_family=AF_INET;
    local_addr.sin_addr.s_addr=INADDR_ANY;
    local_addr.sin_port=htons(PORT);
    if (bind(my_sock,(sockaddr *) &local_addr, sizeof(local_addr)))
    {
    printf("bind error: %d\n",WSAGetLastError());
    closesocket(my_sock);
    WSACleanup();
    return 1;
    }
    // Шаг 4 обработка пакетов, присланных клиентами
    while(1)
    {
    sockaddr_in client_addr;
    int client_addr_size = sizeof(client_addr);
    int bsize=recvfrom(my_sock,&buff[0],sizeof(buff) 1,0,
    (sockaddr *) &client_addr, &client_addr_size);
    if (bsize==SOCKET_ERROR)
    printf("recvfrom() error: %d\n",WSAGetLastError());
    // Определяем IP адрес клиента и прочие атрибуты
    HOSTENT *hst;
    hst=gethostbyaddr((char *) &client_addr.sin_addr,4,AF_INET);
    printf("+%s [%s:%d] new DATAGRAM!\n",
    (hst)?hst >h_name:"Unknown host",
    inet_ntoa(client_addr.sin_addr),
    ntohs(client_addr.sin_port));
    Крис Касперски
    2 20 0
    С
    Са
    ам
    мо
    оууч
    чи
    итте
    ел
    ль
    ь и
    иггр
    ры
    ы н
    на
    а W
    WIIN
    NS
    SO
    OC
    CK
    K

    // добавление завершающего нуля buff[bsize]=0;
    // Вывод на экран
    printf("C=>S:%s\n",&buff[0]);
    // посылка датаграммы клиенту
    sendto(my_sock,&buff[0],bsize,0,
    (sockaddr *)&client_addr, sizeof(client_addr));
    }
    return 0;
    }
    Пример реализации UDP клиента
    // пример простого UDP клиента
    #include
    #include
    #include
    #include
    #define PORT 666
    #define SERVERADDR "127.0.0.1"
    int main(int argc, char* argv[])
    {
    char buff[10*1014];
    printf("UDP DEMO Client\nType quit to quit\n");
    // Шаг 1 иницилизация библиотеки Winsocks
    if (WSAStartup(0x202,(WSADATA *)&buff[0]))
    {
    printf("WSAStartup error: %d\n",WSAGetLastError());
    return 1;
    }
    // Шаг 2 открытие сокета
    SOCKET my_sock=socket(AF_INET, SOCK_DGRAM, 0);
    if (my_sock==INVALID_SOCKET)
    {
    printf("socket() error: %d\n",WSAGetLastError());
    WSACleanup();
    return 1;
    }
    // Шаг 3 обмен сообщений с сервером
    HOSTENT *hst;
    sockaddr_in dest_addr;
    dest_addr.sin_family=AF_INET;
    dest_addr.sin_port=htons(PORT);
    Крис Касперски
    2 21 1
    С
    Са
    ам
    мо
    оууч
    чи
    итте
    ел
    ль
    ь и
    иггр
    ры
    ы н
    на
    а W
    WIIN
    NS
    SO
    OC
    CK
    K

    // определение IP адреса узла if (inet_addr(SERVERADDR))
    dest_addr.sin_addr.s_addr=inet_addr(SERVERADDR);
    else if (hst=gethostbyname(SERVERADDR))
    dest_addr.sin_addr.s_addr=((unsigned long **) hst >h_addr_list)[0][0];
    else
    {
    printf("Unknown host: %d\n",WSAGetLastError());
    closesocket(my_sock);
    WSACleanup();
    return 1;
    }
    while(1)
    {
    // чтение сообщения с клавиатуры printf("S<=C:");fgets(&buff[0],sizeof(buff) 1,stdin);
    if (!strcmp(&buff[0],"quit\n")) break;
    // Передача сообщений на сервер sendto(my_sock,&buff[0],strlen(&buff[0]),0,
    (sockaddr *) &dest_addr,sizeof(dest_addr));
    // Прием сообщения с сервера sockaddr_in server_addr;
    int server_addr_size=sizeof(server_addr);
    int n=recvfrom(my_sock,&buff[0],sizeof(buff) 1,0,
    (sockaddr *) &server_addr, &server_addr_size);
    if (n==SOCKET_ERROR)
    {
    printf("recvfrom() error: %d\n",WSAGetLastError());
    closesocket(my_sock);
    WSACleanup();
    return 1;
    }
    buff[n]=0;
    // Вывод принятого с сервера сообщения на экран printf("S=>C:%s",&buff[0]);
    }
    // Шаг последний выход
    closesocket(my_sock);
    WSACleanup();
    return 0;
    }
    Крис Касперски
    2 22 2
    С
    Са
    ам
    мо
    оууч
    чи
    итте
    ел
    ль
    ь и
    иггр
    ры
    ы н
    на
    а W
    WIIN
    NS
    SO
    OC
    CK
    K
    1   2   3


    написать администратору сайта