Windows Sockets 2. Создание соединения, страница 2

};

Пример:

{

WORD wVersionRequested = MAKEWORD( 2, 2 );

WSADATA wsaData;

int res = WSAStartup( wVersionRequested, &wsaData );

if ( res != 0  )

{

MessageBox("Не могу найти dll или требуемая версия не поддерживается");

}

}

Замечание: когда библиотека уже не нужна, следует вызвать WSACleanUp

2.1.2.  Создание сокета

Требуется создать переменную типа SOCKET

SOCKET m_socket;   //глобальная переменная (или член класса)

Замечание: тип SOCKET – это псевдоним UINT_PTR.  Это эквивалент дескриптора файла. В большинстве случаев его можно использовать в функциях ReadFile (Ex), WriteFile(Ex),DuplicateHandle. Если не удается создать сокет, это значение равно INVALID_SOCKET (эквивалент INVALID_HANDLE_VALUE)

Сокеты создаются функцией socket. Эта функция осуществляет «привязку» сокета к соответствующему транспортному протоколу (transport-service provider). Winsock будет использовать первый найденный функцией socket provider, который удовлетворит запрошенной программистом комбинации: пространство (семейство) адресов, тип сокета, параметры протокола.

SOCKET socket(//возвращаемое значение – «дескриптор» сокета или INVALID_SOCKET. Код ошибки можно получить с помощью WSAGetLastError (-> MSDN)

int af,     //с сокетом должен быть связан адрес, который принадлежит к одному из нескольких семейств адресов. Обычно используется семейство адресов Интернета (32-разрядные значения для протокола IPv4  и 128-разрядные значения в протоколе IPv6). Используйте для IP (компонента протокола Internet в TCP/IP) значение PF_INET или AF_INET (лучше подходит для вызова bind)

int type,   //тип связи, обычно: SOCK_STREAM – для надежного, ориентированного на соединение, байтового обмена. Использует TCP для пространства адресов Интернета, SOCK_DGRAM - ненадежная (не ориентированная на соединение) передача пакетов. Использует UDP для пространства адресов Интернета

int protocol // (WSAEnumProtocols)если af== AF_INET, то можно указать 0. Замечание: указывая различные значения protocol, WinSock можно использовать с другими протоколами (кроме TCP/IP) -> MSDN

Value

Meaning

IPPROTO_TCP

TCP/IP, a connection/stream-oriented protocol.

IPPROTO_UDP

User Datagram Protocol (UDP/IP), a connectionless datagram protocol.

ISOPROTO_TP4

ISO connection-oriented transport protocol.

NSPROTO_IPX

IPX.

NSPROTO_SPX

SPX.

NSPROTO_SPXII

SPX II.

);

Пример:

{

m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

if ( m_socket == INVALID_SOCKET ) {

MessageBox( "Не удалось создать сокет","Сервер" );

WSACleanup();

}

}

2.1.3.  Привязка сокета к сетевому адресу

До сих пор сокет был несвязанным.

Замечание: последовательность вызовов socket()->bind() аналогична созданию именованного канала, но нет имен, благодаря которым различались бы сокеты на данном компьютере. Вместо этого в качестве конечной точки службы указывается номер порта. Обычно сервер использует имя и номер порта, которые известны его клиентам (клиент должен знать адрес и номер порта сервера):

Привязка осуществляется функцией:

int bind( //возвращаемое значение – 0 в случае успеха или SOCKET_ERROR (WSAGetLastError())

SOCKET s,   //”дескриптор” сокета, сформированный функцией socket()

const struct sockaddr FAR* name,     //указатель на заполненную программистом структуру, в которой содержится информация о семействе адресов, IP-адресе и номере порта протоколе и данных для протокола. Замечание: для приложений, использующих IP версию 4 вместо sockaddr используется sockaddr_in

int namelen//sizeof(sockaddr)

);

struct sockaddr_in {

short sin_family;   //AF_INET

u_short sin_port;   //номер порта. Замечание: для преобразования типа short сетевого узла (из собственного формата) в сетевой формат можно использовать функцию htons()

struct in_addr sin_addr; //4-байтовый IP-адрес – 127.0.0.1 – система, от которой принимаются подключения. В принципе можно указывать INADDR_ANY, однако это значение нужно предварительно преобразовать в необходимую форму. Замечание: для преобразования (запаковки) строки IP-адреса в требуемую форму можно использовать функцию inet_addr()

char sin_zero[8];

};

Пример:

{

sockaddr_in service;

service.sin_family = AF_INET;    //семейство адресов Internet

service.sin_addr.s_addr = inet_addr( "127.0.0.1" );   // локальный IP адрес, к которому будет «привязан» сокет

service.sin_port = htons( 27015 );   //номер порта «привязки»

if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR )

{

MessageBox( "bind() failed" ,"server");

closesocket(m_socket);

}

}

протокол HTTP использует порт 80.

2.1.4.  Перевод связанного сокета в режим прослушивания (ожидания)