Netsh Winsock — что это и зачем нужно?
При поиске решений проблем с сетевыми подключениями в интернете пользователи рано или поздно попадают на сайты, на которых говорится о необходимости сброса настроек TCP/IP при помощи специфических команд — netsh winsock reset. Разберемся, что это вообще такое.
Netsh
В приведенной выше команде winsock является только «вложением» (контекстом) в основную команду — netsh. Netsh — это небольшая системная программа (сетевая оболочка), предназначенная для управления сетевыми параметрами Windows и конфигурирования параметров интерфейсов связи сетевых устройств (сетевых плат/адаптеров).
Назначений у программы Netsh довольно много, но чаще всего она используется именно для сброса рабочих параметров TCP/IP. Кроме того, при помощи этой программы (команды) можно изменять IP-адрес, маску подсети, основной шлюз и DNS-сервер любого существующего сетевого подключения (интерфейса).
Winsock
Как отмечалось выше, winsock — один из многочисленных контекстов (будем называть параметров) основной команды netsh. По сути — это техническая спецификация, определяющая способы взаимодействия всего установленного программного обеспечения с сетевыми сервисами, включая TCP/IP. Если простыми словами, Winsock «указывает» какой-либо сетевой программе (браузеру, например), к какому из доступных сетевых подключений ей обращаться для передачи данных во внешнюю сеть.
Как использовать Netsh?
Не будем изобретать велосипед и в качестве примера приведем команды для сброса настроек TCP/IP и изменения основных сетевых параметров одного из подключений.
Сброс TCP/IP при помощи Netsh. Первым делом нужно запустить командную строку Windows от имени администратора (в противном случае система откажет в доступе к своим настройкам):
- Введите в поисковую строку Windows, что расположена в/около меню «Пуск», фразу «командная строка».
- В результатах поиска кликните правой кнопкой мыши по найденному элементу «Командная строка», затем выберите пункт «Запустить от имени администратора».

Для сброса сетевой конфигурации системы обычно достаточно использовать две команды:
netsh int ip reset
netsh winsock reset
Введите их последовательно (завершая ввод клавишей «Enter») в окно командной строки.

В сети по-прежнему можно найти инструкции по сбросу TCP/IP, в которых первой используется другая команда: netsh int ip reset all. В Windows 10 эта команда не работает. Попробуйте ввести ее, получите ошибку. Очень жаль, потому что в параметре int команды netsh содержатся настройки не только для ip, но и для других сетевых объектов.
Если использование netsh int ip reset оказалось недостаточным для «ремонта» сетевого подключения, всегда можно сбросить и другие параметры int, поочередно вводя:
netsh int httpstunnel reset
netsh int ipv6 reset
netsh int tcp reset
netsh int portproxy reset

Если и это не поможет восстановить работоспособность сетевого подключения, проблему следует искать где-нибудь в другом месте (в драйвере, например).
Смена основных сетевых параметров при помощи Netsh. Конечно, эти параметры легче изменить стандартным способом — через свойства интернет-протокола IPv4 конкретного сетевого подключения. Но все же не будет лишним научиться делать это и через Windows-консоль, ведь стандартный способ может и не сработать, особенно, если компьютер заражен каким-нибудь вирусом-блокировщиком.
Для начала нужно узнать имя сетевого интерфейса, с которым предстоит работать. Для этого используем команду:
netsh int show interface
В нашем случае имеется всего одно единственное подключение, имя которого — Ethernet (это обычное подключение по локальной сети).
Меняем IP-адрес, маску подсети и основной шлюз на требуемом интерфейсе. Для этого используем команду:
netsh int ip set address ethernet static 192.168.0.25 255.255.255.0 192.168.0.1

- Параметр ethernet — имя перенастраиваемого сетевого подключения. Если в имени содержаться пробелы (например, оно названо «Подключение по локальной сети Ethernet»), его необходимо писать в кавычках — » Подключение по локальной сети Ethernet «.
- Параметр static указывает, что устанавливаемые сетевые параметры будут являться статичными. Т.е. процедура по смене IP, маски и шлюза через командную строку равнозначна процедуре смены сетевых параметров стандартным способом.
- Параметр 168.0.25 — новый IP-адрес для нашего подключения.
- Параметр 255.255.0 — новая маска подсети.
- Параметр 168.0.1 — новый основной шлюз.
Возникает вопрос — а где новый DNS-сервер? Этот параметр не является обязательным — он, скорее, добавочный. Т.е. нам предстоит добавить новый элемент в наше сетевое подключение. Делается это следующим образом:
netsh int ip add dnsserver ethernet 8.8.4.4

Здесь, впрочем, все понятно. Указанный нами DNS-сервер — это общедоступный сервер от Google. Вы можете использовать вместо него DNS, выданный вашим интернет-провайдером.
Кстати, если использовать команду повторно с другим адресом DNS-сервера, он запишется в поле «Альтернативный DNS-сервер».
Результат выполнения команды можно посмотреть в свойствах сетевого подключения:

Остались вопросы, предложения или замечания? Свяжитесь с нами и задайте вопрос.
Winsock что это такое
И так, что же такое Winsock и с чем его едят? Если сказать в "двух словах", то Winsock это интерфейс, который упрощает разработку сетевых приложений под Windows. Всё что нам нужно знать, это то что Winsock представляет собою интерфейс между приложением и транспортным протоколом, выполняющим передачу данных.
Не будем вдаваться в детали внутренней архитектуры, ведь нас интересует не то, как он устроен внутри, а то, как использовать функции, предоставляемые Winsock пользователю для работы. Наша задача — на конкретных примерах разобраться с механизмом действия WinsockAPI. "Для чего это можно использовать? Ведь существуют библиотеки, упрощающие работу с сетями и имеющие простой интерфейс?" — спросите вы. Я отчасти согласен с этим утверждением, но по-моему полностью универсальных библиотек, ориентированных под все задачи существовать не может. Да и к тому же, намного приятней разобраться во всём самому, не чувствуя неловкости перед "чёрным ящиком" принципа работы которого не понимаешь, а лишь используешь как инструмент 🙂 Весь материал рассчитан на новичков. Я думаю с его освоением не будет никаких проблем. Если вопросы всё-таки возникнут, пишите на pepper@anotherd.com. Отвечу всем. Для иллюстрации примеров будем использовать фрагменты кода Microsoft VC++. Итак, приступим!
Итак, первый вопрос — если есть Winsock, то как его использовать? На деле всё не так уж и сложно. Этап первый — подключение библиотек и заголовков.
#include "winsock.h" или #include "winsock2.h" — в зависимости от того, какую версию Winsock вы будете использовать
Так же в проект должны быть включены все соответствующие lib-файлы (Ws2_32.lib или Wsock32.lib)
Теперь мы можем спокойно использовать функции WinsockAPI. (полный список функций можно найти в соответствующих разделах MSDN).
Для инициализации Winsock вызываем функцию WSAStartup
Параметр WORD wVersionRequested — младший байт — версия, старший байт — под.версия, интерфейса Winsock. Возможные версии — 1.0, 1.1, 2.0, 2.2. Для "сборки" этого параметра используем макрос MAKEWORD. Например: MAKEWORD (1, 1) — версия 1.1. Более поздние версии отличаются наличием новых функций и механизмов расширений. Параметр lpWSAData — указатель на структуру WSADATA. При возврате из функции данная структура содержит информацию о проинициализированной нами версии WinsockAPI. В принципе, ёё можно игнорировать, но если кому-то будет интересно что же там внутри — не поленитесь, откройте документацию 😉
Так это выглядит на практике:
При ошибке функция возвращает SOCKET_ERROR. В таком случае можно получить расширенную информацию об ошибке используя вызов WSAGetLastError(). Данная функция возвращает код ошибки (тип int)
Итак, мы можем приступить к следующему этапу — создания основного средства коммуникации в Winsock- сокета (socket). С точки зрения WinsockAPI сокет — это дескриптор, который может получать или отправлять данные. На практике всё выглядит так: мы создаём сокет с определёнными свойствами и используем его для подключения, приёма/передачи данных и т.п. А теперь сделаем небольшое отступление. Итак, создавая сокет мы должны указать его параметры: сокет использует TCP/IP протокол или IPX (если TCP/IP, то какой тип и т.д.). Так как следующие разделы данной статьи будут ориентированы на TCP/IP протокол, то остановимся на особенностях сокетов использующих этот протокол. Мы можем создать два основных типа сокетов работающих по TCP/IP протоколу — SOCK_STREAM и SOCK_DGRAM (RAW socket пока оставим в покое 🙂 ). Разница в том, что для первого типа сокетов (их еще называют TCP или connection-based socket), для отправки данных сокет должен постоянно поддерживать соединение с адресатом, при этом доставка пакета адресату гарантирована. Во втором случае наличие постоянного соединения не нужно, но информацию о том, дошел ли пакет, или нет — получить невозможно (так называемые UDP или connectionless sockets). И первый и второй типы сокетов имеют своё практическое применение. Начнём наше знакомство с сокетами с TCP (connection-based) сокетов.
Для начала объявим его:
При ошибке функция возвращает INVALID_SOCKET. В таком случае можно получить расширенную информацию об ошибке используя вызов WSAGetLastError().
В предыдущем примере мы создали сокет. Что же теперь с ним делать? 🙂 Теперь мы можем использовать этот сокет для обмена данными с другими клиентами winsock-клиентами и не только. Для того, что бы установить соединение с другой машиной необходимо знать ее IP адрес и порт. Удалённая машина должна "слушать" этот порт на предмет входящих соединений (т.е. она выступает в качестве сервера). В таком случае наше приложение это клиент.
Для установки соединения используем функцию connect.
// Объявим переменную для хранения адреса
sockaddr_in s_addr;
// Заполним ее:
ZeorMemory (&s_addr, sizeof (s_addr));
// тип адреса (TCP/IP)
s_addr.sin_family = AF_INET;
//адрес сервера. Т.к. TCP/IP представляет адреса в числовом виде, то для перевода
// адреса используем функцию inet_addr.
s_addr.sin_addr.S_un.S_addr = inet_addr ("193.108.128.226");
// Порт. Используем функцию htons для перевода номера порта из обычного в //TCP/IP представление.
s_addr.sin_port = htons (1234);
// Дальше выполняем соединение:
if (SOCKET_ERROR == ( connect (s, (sockaddr *) &s_addr, sizeof (s_addr) ) ) )
<
// Error.
error = WSAGetLastError();
// .
>
При ошибке функция возвращает SOCKET_ERROR.
Теперь сокет s связан с удаленной машиной и может посылать/принимать данные только с нее.
Для того что бы послать данные используем функцию send
При ошибке функция возвращает SOCKET_ERROR.
Длинна пакета данных ограничена самим протоколом. Как узнать максимальную длину пакета данных мы рассмотрим в следующий раз. Возврат из функции не происходит до тех пор, пока данные не будут отправлены.
Принять данные от машины с которой мы предварительно установили соединение позволяет функция recv.
int actual_len = 0;
if (SOCKET_ERROR == (actual_len = recv (s, (char* ) & buff), max_packet_size, 0 ) )
<
// Error.
error = WSAGetLastError();
// .
>
Если данные получены, то функция возвращает размер полученного пакета данных (а примере — actual_len) При ошибке функция возвращает SOCKET_ERROR. Заметьте, что функции send/recv будут ждать пока не выйдет тайм-аут или не отправится/придет пакет данных. Это соответственно вызывает задержку в работе программы. Как этого избежать читайте в следующих выпусках.
Процедура закрытия активного соединения происходит с помощью функций shutdown и closesocket. Различают два типа закрытия соединений: abortive и graceful. Первый вид — это экстренное закрытие сокета (closesocket). В таком случае соединение разрывается моментально. Вызов closesocket имеет мгновенный еффект. После вызова closesocket сокет уже недоступен. Как закрыть сокет с помощью shutdown/closesocket читайте в следующих выпусках, так как эта тема требует более полного знания Winsock.
Winsock что это такое
WinSock или Windows socket — это интерфейс программного программирования (API) созданный для реализации приложений в сети на основе протокола TCP/IP. То есть это просто группа функций . Для работы используется WSOCK32.DLL.
Практически это интерфейс к протоколу TCP/IP.
При взаимодействии клиент — сервер в сети каждого участника взаимодействия можно рассматривать как конечную точку. Сокет это вроде как и есть эта конечная точка. В приложении Вы определяете сокет. И хоть программирование сокетов в UNIX и Windows похоже, мы с Вами будем рассматривать именно Windows socket.
Незнаю интересно это или нет, но Windows socket разрабатывался на основе интерфейса Беркли для UNIX, но к ним добавлены функции поддержки событий Windows.
- WinSock 1.1 — поддержка только TCP/IP
- WinSock 2.0 — Поддерка дополнительного программного обеспечения
- Функции Беркли
- Информационные функции (получение информации о наименовании доменов, службах, протоколах Internet)
- Расширения Windows для функций Беркли
Все функции могут быть блокирующие и неблокирующие. Обычно блокирующие это функции Беркли. То есть при работе такой функции нельзя выполнять другие функции WinSock.
Давайте расмотрим как производится подключение к серверу. Сначала программа подключается к адресу IP с созданием сокета. Программа будет ждать подключения. Для подключения программа клиент тоже создает сокет и пытается подключиться к сокету сервера. Но сервер не спит . Только он увидит попытку подключения он создаст новый сокет. И этот новый сокет будет использоваться для взаимодействия с клиентом. А тот, к которому была попытка подключения будет ждать следующего. На этой основе производится взаимодействие сервера и многими программами.