Самоучитель игры на winsock

The socket function creates a socket that is bound to a specific transport service provider.

Syntax

Parameters

The address family specification. Possible values for the address family are defined in the Winsock2.h header file.

On the Windows SDK released for WindowsВ Vista and later, the organization of header files has changed and the possible values for the address family are defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically included in Winsock2.h, and should never be used directly.

The values currently supported are AF_INET or AF_INET6, which are the Internet address family formats for IPv4 and IPv6. Other options for address family (AF_NETBIOS for use with NetBIOS, for example) are supported if a Windows Sockets service provider for the address family is installed. Note that the values for the AF_ address family and PF_ protocol family constants are identical (for example, AF_INET and PF_INET), so either constant can be used.

The table below lists common values for address family although many other values are possible.

Af Meaning
AF_UNSPEC 0 The address family is unspecified.
AF_INET 2 The Internet Protocol version 4 (IPv4) address family.
AF_IPX 6 The IPX/SPX address family. This address family is only supported if the NWLink IPX/SPX NetBIOS Compatible Transport protocol is installed.

This address family is not supported on WindowsВ Vista and later.

AF_APPLETALK 16 The AppleTalk address family. This address family is only supported if the AppleTalk protocol is installed.

This address family is not supported on WindowsВ Vista and later.

AF_NETBIOS 17 The NetBIOS address family. This address family is only supported if the Windows Sockets provider for NetBIOS is installed.

The Windows Sockets provider for NetBIOS is supported on 32-bit versions of Windows. This provider is installed by default on 32-bit versions of Windows.

The Windows Sockets provider for NetBIOS is not supported on 64-bit versions of windows including WindowsВ 7, Windows ServerВ 2008, WindowsВ Vista, Windows ServerВ 2003, or WindowsВ XP.

The Windows Sockets provider for NetBIOS only supports sockets where the type parameter is set to SOCK_DGRAM.

The Windows Sockets provider for NetBIOS is not directly related to the NetBIOS programming interface. The NetBIOS programming interface is not supported on WindowsВ Vista, Windows ServerВ 2008, and later.

AF_INET6 23 The Internet Protocol version 6 (IPv6) address family. AF_IRDA 26 The Infrared Data Association (IrDA) address family.

This address family is only supported if the computer has an infrared port and driver installed.

AF_BTH 32 The Bluetooth address family.

This address family is supported on WindowsВ XP with SP2 or later if the computer has a Bluetooth adapter and driver installed.

The type specification for the new socket.

Possible values for the socket type are defined in the Winsock2.h header file.

The following table lists the possible values for the type parameter supported for Windows Sockets 2:

Type Meaning
SOCK_STREAM 1 A socket type that provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. This socket type uses the Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6).
SOCK_DGRAM 2 A socket type that supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. This socket type uses the User Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6).
SOCK_RAW 3 A socket type that provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To manipulate the IPv4 header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the IPV6_HDRINCL socket option must be set on the socket.
SOCK_RDM 4 A socket type that provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) multicast protocol implementation in Windows, often referred to as reliable multicast programming.

This type value is only supported if the Reliable Multicast Protocol is installed.

SOCK_SEQPACKET 5 A socket type that provides a pseudo-stream packet based on datagrams.

В

In Windows Sockets 2, new socket types were introduced. An application can dynamically discover the attributes of each available transport protocol through the WSAEnumProtocols function. So an application can determine the possible socket type and protocol options for an address family and use this information when specifying this parameter. Socket type definitions in the Winsock2.h and Ws2def.h header files will be periodically updated as new socket types, address families, and protocols are defined.

In Windows Sockets 1.1, the only possible socket types are SOCK_DGRAM and SOCK_STREAM.

The protocol to be used. The possible options for the protocol parameter are specific to the address family and socket type specified. Possible values for the protocol are defined in the Winsock2.h and Wsrm.h header files.

Читайте также  Работа для людей с дцп

On the Windows SDK released for WindowsВ Vista and later, the organization of header files has changed and this parameter can be one of the values from the IPPROTO enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically included in Winsock2.h, and should never be used directly.

If a value of 0 is specified, the caller does not wish to specify a protocol and the service provider will choose the protocol to use.

When the af parameter is AF_INET or AF_INET6 and the type is SOCK_RAW, the value specified for the protocol is set in the protocol field of the IPv6 or IPv4 packet header.

The table below lists common values for the protocol although many other values are possible.

protocol Meaning
IPPROTO_ICMP 1 The Internet Control Message Protocol (ICMP). This is a possible value when the af parameter is AF_UNSPEC, AF_INET, or AF_INET6 and the type parameter is SOCK_RAW or unspecified.

This protocol value is supported on WindowsВ XP and later.

IPPROTO_IGMP 2 The Internet Group Management Protocol (IGMP). This is a possible value when the af parameter is AF_UNSPEC, AF_INET, or AF_INET6 and the type parameter is SOCK_RAW or unspecified.

This protocol value is supported on WindowsВ XP and later.

BTHPROTO_RFCOMM 3 The Bluetooth Radio Frequency Communications (Bluetooth RFCOMM) protocol. This is a possible value when the af parameter is AF_BTH and the type parameter is SOCK_STREAM.

This protocol value is supported on WindowsВ XP with SP2 or later.

IPPROTO_TCP 6 The Transmission Control Protocol (TCP). This is a possible value when the af parameter is AF_INET or AF_INET6 and the type parameter is SOCK_STREAM. IPPROTO_UDP 17 The User Datagram Protocol (UDP). This is a possible value when the af parameter is AF_INET or AF_INET6 and the type parameter is SOCK_DGRAM. IPPROTO_ICMPV6 58 The Internet Control Message Protocol Version 6 (ICMPv6). This is a possible value when the af parameter is AF_UNSPEC, AF_INET, or AF_INET6 and the type parameter is SOCK_RAW or unspecified.

This protocol value is supported on WindowsВ XP and later.

IPPROTO_RM 113 The PGM protocol for reliable multicast. This is a possible value when the af parameter is AF_INET and the type parameter is SOCK_RDM. On the Windows SDK released for WindowsВ Vista and later, this protocol is also called IPPROTO_PGM.

This protocol value is only supported if the Reliable Multicast Protocol is installed.

Return value

If no error occurs, socket returns a descriptor referencing the new socket. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error code Meaning
WSANOTINITIALISED A successful WSAStartup call must occur before using this function.
WSAENETDOWN The network subsystem or the associated service provider has failed.
WSAEAFNOSUPPORT The specified address family is not supported. For example, an application tried to create a socket for the AF_IRDA address family but an infrared adapter and device driver is not installed on the local computer.
WSAEINPROGRESS A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAEMFILE No more socket descriptors are available.
WSAEINVAL An invalid argument was supplied. This error is returned if the af parameter is set to AF_UNSPEC and the type and protocol parameter are unspecified.
WSAEINVALIDPROVIDER The service provider returned a version other than 2.2.
WSAEINVALIDPROCTABLE The service provider returned an invalid or incomplete procedure table to the WSPStartup.
WSAENOBUFS No buffer space is available. The socket cannot be created.
WSAEPROTONOSUPPORT The specified protocol is not supported.
WSAEPROTOTYPE The specified protocol is the wrong type for this socket.
WSAEPROVIDERFAILEDINIT The service provider failed to initialize. This error is returned if a layered service provider (LSP) or namespace provider was improperly installed or the provider fails to operate correctly.
WSAESOCKTNOSUPPORT The specified socket type is not supported in this address family.

Remarks

The socket function causes a socket descriptor and any related resources to be allocated and bound to a specific transport-service provider. Winsock will utilize the first available service provider that supports the requested combination of address family, socket type and protocol parameters. The socket that is created will have the overlapped attribute as a default. For Windows, the Microsoft-specific socket option, SO_OPENTYPE, defined in Mswsock.h can affect this default. See Microsoft-specific documentation for a detailed description of SO_OPENTYPE.

Sockets without the overlapped attribute can be created by using WSASocket. All functions that allow overlapped operation (WSASend, WSARecv, WSASendTo, WSARecvFrom, and WSAIoctl) also support nonoverlapped usage on an overlapped socket if the values for parameters related to overlapped operation are NULL.

Читайте также  Почему поливают дороги в дождь

When selecting a protocol and its supporting service provider this procedure will only choose a base protocol or a protocol chain, not a protocol layer by itself. Unchained protocol layers are not considered to have partial matches on type or af either. That is, they do not lead to an error code of WSAEAFNOSUPPORT or WSAEPROTONOSUPPORT if no suitable protocol is found.

Connection-oriented sockets such as SOCK_STREAM provide full-duplex connections, and must be in a connected state before any data can be sent or received on it. A connection to another socket is created with a connect call. Once connected, data can be transferred using send and recv calls. When a session has been completed, a closesocket must be performed.

The communications protocols used to implement a reliable, connection-oriented socket ensure that data is not lost or duplicated. If data for which the peer protocol has buffer space cannot be successfully transmitted within a reasonable length of time, the connection is considered broken and subsequent calls will fail with the error code set to WSAETIMEDOUT.

Connectionless, message-oriented sockets allow sending and receiving of datagrams to and from arbitrary peers using sendto and recvfrom. If such a socket is connected to a specific peer, datagrams can be sent to that peer using send and can be received only from this peer using recv.

IPv6 and IPv4 operate differently when receiving a socket with a type of SOCK_RAW. The IPv4 receive packet includes the packet payload, the next upper-level header (for example, the IP header for a TCP or UDP packet), and the IPv4 packet header. The IPv6 receive packet includes the packet payload and the next upper-level header. The IPv6 receive packet never includes the IPv6 packet header.

When the af parameter is AF_NETBIOS for NetBIOS over TCP/IP, the type parameter can be SOCK_DGRAM or SOCK_SEQPACKET. For the AF_NETBIOS address family, the protocol parameter is the LAN adapter number represented as a negative number.

On WindowsВ XP and later, the following command can be used to list the Windows Sockets catalog to determine the service providers installed and the address family, socket type, and protocols that are supported.

netsh winsock show catalog

Support for sockets with type SOCK_RAW is not required, but service providers are encouraged to support raw sockets as practicable.

Notes for IrDA Sockets

Example Code

WindowsВ PhoneВ 8: This function is supported for Windows Phone Store apps on WindowsВ PhoneВ 8 and later.

WindowsВ 8.1 and Windows ServerВ 2012В R2: This function is supported for Windows Store apps on WindowsВ 8.1, Windows ServerВ 2012В R2, and later.

И так, что же такое 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.

При ошибке функция возвращает SOCKET_ERROR.
Теперь сокет s связан с удаленной машиной и может посылать/принимать данные только с нее.

Для того что бы послать данные используем функцию send

При ошибке функция возвращает SOCKET_ERROR.
Длинна пакета данных ограничена самим протоколом. Как узнать максимальную длину пакета данных мы рассмотрим в следующий раз. Возврат из функции не происходит до тех пор, пока данные не будут отправлены.

Принять данные от машины с которой мы предварительно установили соединение позволяет функция recv.

Если данные получены, то функция возвращает размер полученного пакета данных (а примере — actual_len) При ошибке функция возвращает SOCKET_ERROR. Заметьте, что функции send/recv будут ждать пока не выйдет тайм-аут или не отправится/придет пакет данных. Это соответственно вызывает задержку в работе программы. Как этого избежать читайте в следующих выпусках.

Процедура закрытия активного соединения происходит с помощью функций shutdown и closesocket. Различают два типа закрытия соединений: abortive и graceful. Первый вид — это экстренное закрытие сокета (closesocket). В таком случае соединение разрывается моментально. Вызов closesocket имеет мгновенный еффект. После вызова closesocket сокет уже недоступен. Как закрыть сокет с помощью shutdown/closesocket читайте в следующих выпусках, так как эта тема требует более полного знания Winsock.

Как видите, рассмотренный нами Winsock-механизм обмена данными очень прост. От программиста требуется лишь выработать свой "протокол" общения удалённых машин и реализовать его с помощью данных функций. Конечно, рассмотренные нами примеры не отражают всех возможностей Winsock. В наших статьях мы постараемся рассмотреть наиболее важные на наш взгляд особенности работы с Winsock. Stay tuned. 🙂
В следующем выпуске читайте:

  • Пишем простейшее winsock приложение.
  • UDP сокеты — приём/доставка негарантированных пакетов
  • Решаем проблему "блокировки" сокетов.

sergg

По этой функции у меня возникло несколько вопросов:
1) в строке "my_sock=((SOCKET *) client_socket)[0];" что значит [0]?
2) что значит DWORD WINAPI? Прошу не отправлять меня читать про WinApi. Я представляю что это такое, как и для чего используется. Просто прошу пояснить, что значат эти два слова перед описанием функции.
3) Ну и самый главный вопрос, который у меня возник. Как отправлять сообщение пользователя не ему самому, а всем пользователям сразу?
Я так понимаю, что надо как-то создать массив типа SOCKET, в котором будут хранится все сокеты, по которым подключены клиенты, и в цикле отправлять это сообщение всем, но как это сделать в потоке? Или может есть еще какие-нибудь варианты?

Подскажите, пожалуйста, ответы на эти вопросы.

Ссылка на основную публикацию
Adblock
detector