| Tenouk.com | Winsock Program Example 1 | Main | Winsock Program Example 3 >| Site Index | Download |


 

WINSOCK 2

WINDOWS SOCKET: PROGRAM EXAMPLES PART 2

 

 

 

Winsock Tutorial

 

Winsock: Story 1

Winsock: Story 2

Winsock: Story 3

Winsock: Example 1

Winsock: Example 2

Winsock: Example 3

Winsock: Example 4

Winsock: Example 5

Winsock: Example 6

Winsock: Example 7

Winsock: Example 8

Winsock: Example 9

Winsock: Example 10

Winsock: Example 11

Winsock: Example 12

Winsock: Reference 1

Winsock: Reference 2

Winsock: Reference 3

Winsock: Reference 4

My Training Period:          hours

 

Note:

This is a continuation from previous Module.

Machine’s OS is standalone Windows Xp Pro with SP2 except whenever mentioned.  Compiler used was Visual C++ 2003 .Net 1.1. Beware the codes that span more than one line.  Program examples have been tested for Non Destructive Test :o).  All information compiled for Windows 2000 (NT5.0) above and...

 

  1. The story was discussed at Winsock introduction story.
  2. Related functions, structures and macros used in the program examples have been dumped at Winsock structure & function 1 and Winsock structure & function 2.
  3. Other related and required information (if any) not available in no. 2 can be found at MSDN & Visual C++ online reference.

 

Abilities

 

         Able to understand the basic of networking such as TCP/IP.

         Able to understand Winsock implementation and operations through the APIs and program examples.

         Able to gather, understand and use the Winsock functions, structures and macros in your programs.

         Able to build programs that use Microsoft C/Standard C programming language and Winsock APIs.

 

socket()

 

Item

Description

Function

socket().

Use

To create a socket that is bound to a specific service provider.

Prototype

SOCKET socket(int af, int type, int protocol);

Parameters

See below.

Return value

See below.

Include file

<winsock2.h>

Library

ws2_32.lib.

Remark

See below

 

Table 1

 

af

[in] Address family specification.

 

type

[in] Type specification for the new socket.

The following are the only two type specifications supported for Windows Sockets 1.1 and for Winsock 2 there are support for RAW Socket, SOCK_RAW.

 

Type

Meaning

SOCK_STREAM

Provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. Uses TCP (Transport Control Protocol) for the Internet address family.

SOCK_DGRAM

Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Uses UDP (User Datagram Protocol) for the Internet address family.

 

Table 2

 

In Windows Sockets 2, many new socket types will be introduced and no longer need to be specified, since an application can dynamically discover the attributes of each available transport protocol through the WSAEnumProtocols() function. Socket type definitions appear in winsock2.h, which will be periodically updated as new socket types, address families, and protocols are defined.

 

protocol

[in] Protocol to be used with the socket that is specific to the indicated address family.

 

Return Values

 

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.

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.

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.

WSAESOCKTNOSUPPORT

The specified socket type is not supported in this address family.

 

Table 3

 

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. 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 non-overlapped 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.

 

 

 

Some note

 

The manifest constant AF_UNSPEC continues to be defined in the header file but its use is strongly discouraged, as this can cause ambiguity in interpreting the value of the protocol parameter. 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().

Support for sockets with type SOCK_RAW (RAW socket) is not required, but service providers are encouraged to support raw sockets as practicable. On Windows NT, raw socket support requires administrative privileges.

 

Notes for IrDA Sockets

 

Keep the following in mind:

 

          The af_irda.h header file must be explicitly included.

          Only SOCK_STREAM is supported; the SOCK_DGRAM type is not supported by IrDA.

          The protocol parameter is always set to 0 for IrDA.

 

Program Example

 

// Microsoft Development Environment 2003 - Version 7.1.3088

// Copyright (r) 1987-2002 Microsoft Corporation. All Right Reserved

// Microsoft .NET Framework 1.1 - Version 1.1.4322

// Copyright (r) 1998-2002 Microsoft Corporation. All Right Reserved

//

// Run on Windows XP Pro machine, version 2002, SP 2

//

// <windows.h> already included

// WINVER = 0x0501 for Xp already defined in windows.h

 

#include <stdio.h>

#include <winsock2.h>

 

int main()

{

WORD wVersionRequested;

WSADATA wsaData;

int wsaerr;

 

// Using MAKEWORD macro, Winsock version request 2.2

wVersionRequested = MAKEWORD(2, 2);

 

wsaerr = WSAStartup(wVersionRequested, &wsaData);

if (wsaerr != 0)

{

    /* Tell the user that we could not find a usable */

    /* WinSock DLL.*/

    printf("The Winsock dll not found!\n");

    return 0;

}

 

else

{

       printf("The Winsock dll found!\n");

       printf("The status: %s.\n", wsaData.szSystemStatus);

}

 

/* Confirm that the WinSock DLL supports 2.2.        */

/* Note that if the DLL supports versions greater    */

/* than 2.2 in addition to 2.2, it will still return */

/* 2.2 in wVersion since that is the version we      */

/* requested.                                        */

if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)

{

    /* Tell the user that we could not find a usable */

    /* WinSock DLL.*/

    printf("The dll do not support the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion));

    WSACleanup();

    return 0;

}

 

else

{

       printf("The dll supports the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion));

       printf("The highest version this dll can support: %u.%u\n", LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion));

}

 

//////////Create a socket////////////////////////

//Create a SOCKET object called m_socket.

SOCKET m_socket;

 

// Call the socket function and return its value to the m_socket variable.

// For this application, use the Internet address family, streaming sockets, and

// the TCP/IP protocol.

// using AF_INET family, TCP socket type and protocol of the AF_INET - IPv4

m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

 

// Check for errors to ensure that the socket is a valid socket.

if (m_socket == INVALID_SOCKET)

{

    printf("Error at socket(): %ld\n", WSAGetLastError());

    WSACleanup();

    return 0;

}

else

{

       printf("socket() is OK!\n");

}

 

return 0;

}

 

Windows socket program example output screen: using socket()

 

Figure 1

 

bind()

 

Item

Description

Function

bind().

Use

Associates a local address with a socket.

Prototype

int bind(SOCKET s, const struct sockaddr* name, int namelen);

Parameters

s

[in] Descriptor identifying an unbound socket.

 

name

[in] Address to assign to the socket from the sockaddr structure.

 

namelen

[in] Length of the value in the name parameter, in bytes.

Return value

See below.

Include file

<winsock2.h.>

Library

ws2_32.lib

Remark

See below.

 

Table 4

 

Return Values

 

If no error occurs, bind() returns zero. Otherwise, it returns SOCKET_ERROR, 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 has failed.

WSAEACCES

Attempt to connect datagram socket to broadcast address failed because setsockopt() option SO_BROADCAST is not enabled.

WSAEADDRINUSE

A process on the computer is already bound to the same fully-qualified address and the socket has not been marked to allow address reuse with SO_REUSEADDR. For example, the IP address and port are bound in the AF_INET case). (See the SO_REUSEADDR socket option under setsockopt().)

WSAEADDRNOTAVAIL

The specified address is not a valid address for this computer.

WSAEFAULT

The name or namelen parameter is not a valid part of the user address space, the namelen parameter is too small, the name parameter contains an incorrect address format for the associated address family, or the first two bytes of the memory block specified by name does not match the address family associated with the socket descriptor s.

WSAEINPROGRESS

A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

WSAEINVAL

The socket is already bound to an address.

WSAENOBUFS

Not enough buffers available, too many connections.

WSAENOTSOCK

The descriptor is not a socket.

 

Table 5

 

Remarks

 

The bind() function is used on an unconnected socket before subsequent calls to the connect() or listen() functions. It is used to bind to either connection-oriented (stream – TCP – Transmission Control Protocol) or connectionless (datagram – UDP – User Datagram Protocol) sockets. When a socket is created with a call to the socket() function, it exists in a namespace (address family), but it has no name assigned to it. Use the bind() function to establish the local association of the socket by assigning a local name to an unnamed socket. A name consists of three parts when using the Internet address family:

 

          The address family.

          A host address.

          A port number that identifies the application.

 

In Windows Sockets 2, the name parameter is not strictly interpreted as a pointer to a sockaddr structure. It is cast this way for Windows Sockets 1.1 compatibility. Service providers are free to regard it as a pointer to a block of memory of size namelen. The first 2 bytes in this block (corresponding to the sa_family member of the sockaddr structure) must contain the address family that was used to create the socket. Otherwise, an error WSAEFAULT occurs.

If an application does not care what local address is assigned, specify the manifest constant value ADDR_ANY for the sa_data member of the name parameter. This allows the underlying service provider to use any appropriate network address, potentially simplifying application programming in the presence of multihomed hosts that is, hosts that have more than one network interface and address.

For TCP/IP, if the port is specified as zero, the service provider assigns a unique port to the application with a value between 1024 and 5000. The application can use getsockname() after calling bind() to learn the address and the port that has been assigned to it. If the Internet address is equal to INADDR_ANY, getsockname() cannot necessarily supply the address until the socket is connected, since several addresses can be valid if the host is multihomed. Binding to a specific port number other than port 0 is discouraged for client applications, since there is a danger of conflicting with another socket already using that port number. When using bind() with the SO_EXCLUSIVEADDR or SO_REUSEADDR socket option, the socket option must be set prior to executing bind() to have any affect.

 

Program Example

 

// Microsoft Development Environment 2003 - Version 7.1.3088

// Copyright (r) 1987-2002 Microsoft Corporation. All Right Reserved

// Microsoft .NET Framework 1.1 - Version 1.1.4322

// Copyright (r) 1998-2002 Microsoft Corporation. All Right Reserved

//

// Run on Windows XP Pro machine, version 2002, SP 2

//

// <windows.h> already included

// WINVER = 0x0501 for Xp already defined in windows.h

 

#include <stdio.h>

#include <winsock2.h>

 

int main()

{

WORD wVersionRequested;

WSADATA wsaData;

int wsaerr;

 

// Using MAKEWORD macro, Winsock version request 2.2

wVersionRequested = MAKEWORD(2, 2);

 

wsaerr = WSAStartup(wVersionRequested, &wsaData);

if (wsaerr != 0)

{

    /* Tell the user that we could not find a usable */

    /* WinSock DLL.*/

    printf("The Winsock dll not found!\n");

    return 0;

}

else

{

       printf("The Winsock dll found!\n");

       printf("The status: %s.\n", wsaData.szSystemStatus);

}

 

/* Confirm that the WinSock DLL supports 2.2.*/

/* Note that if the DLL supports versions greater    */

/* than 2.2 in addition to 2.2, it will still return */

/* 2.2 in wVersion since that is the version we      */

/* requested.                                        */

if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)

{

    /* Tell the user that we could not find a usable */

    /* WinSock DLL.*/

    printf("The dll do not support the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));

    WSACleanup();

    return 0;

}

else

{

    printf("The dll supports the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));

    printf("The highest version this dll can support: %u.%u\n", LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion));

}

 

//////////Create a socket////////////////////////

//Create a SOCKET object called m_socket.

SOCKET m_socket;

 

// Call the socket function and return its value to the m_socket variable.

// For this application, use the Internet address family, streaming sockets, and

// the TCP/IP protocol.

// using AF_INET family, TCP socket type and protocol of the AF_INET - IPv4

m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

 

// Check for errors to ensure that the socket is a valid socket.

if (m_socket == INVALID_SOCKET)

{

    printf("Error at socket(): %ld.\n", WSAGetLastError());

    WSACleanup();

    return 0;

}

else

{

    printf("socket() is OK!\n");

}

 

////////////////bind()//////////////////////////////

// Create a sockaddr_in object and set its values.

sockaddr_in service;

 

// AF_INET is the Internet address family.

service.sin_family = AF_INET;

// "127.0.0.1" is the local IP address to which the socket will be bound.

service.sin_addr.s_addr = inet_addr("127.0.0.1");

// 55555 is the port number to which the socket will be bound.

service.sin_port = htons(55555);

 

// Call the bind function, passing the created socket and the sockaddr_in structure as parameters.

// Check for general errors.

 

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

{

    printf("bind() failed: %ld.\n", WSAGetLastError());

    closesocket(m_socket);

    return 0;

}

else

{

   printf("bind() is OK!\n");

}

 

return 0;

}

 

 

Figure 2

 

Another example demonstrates the use of the bind() function.

 

#include <stdio.h>

#include <winsock2.h>