Chapter 27
27.1 INTRODUCTION
2
27.2 WELL KNOWN
PROTOCOLS
2
27.3 DNS (DOMAIN
NAME
SYSTEMS)
2
27.4 WELL KNOWN
HOST NAMES ON THE INTERNET 3
27.5 WINDOWS
SOCKETS
3
27.6 BASIC
SOCKETS
OPERATIONS
3
27.7 WINDOWS
SOCKET
LIBRARY
4
27.8 WINSOCK
INITIALIZATION
4
Example Code 6
SUMMARY
7
EXERCISES
7
Network Programming Part I
2
27.1 Introduction
Following are the some of the concept of packet information.
These concepts will be used
in network programming.
• IP addresses and ports
• The structure of an IP
packet
• Protocol
• Connection-oriented vs.
datagram protocols
• IP, TCP and UDP
• HTTP, other wrapper
protocols
27.2 Well known Protocols
Following are the well known protocols used today.
27.5 Windows Sockets
Windows Sockets (Winsock) enables programmers to create advanced
Internet,
intranet, and other network-capable applications to transmit
application data across
the wire, independent of the network protocol being used. With
Winsock,
programmers are provided access to advanced Microsoft® Windows®
networking
capabilities such as multicast and Quality of Service (QOS).
Winsock follows the Windows Open System Architecture (WOSA)
model; it defines a
standard service provider interface (SPI) between the
application programming
interface (API), with its exported functions and the protocol
stacks. It uses the
sockets paradigm that was first popularized by Berkeley Software
Distribution (BSD)
UNIX. It was later adapted for Windows in Windows Sockets 1.1,
with which
Windows Sockets 2 applications are backward compatible. Winsock
programming
previously centered on TCP/IP. Some programming practices that
worked with
TCP/IP do not work with every protocol. As a result, the Windows
Sockets 2 API adds
functions where necessary to handle several protocols.
27.6 Basic Sockets Operations
The following are the basic operations performed by both server
and client systems.
1. Create an unbound socket
2. Binding Server
3. Connecting Client
4. Listen
5. Accept
6. Send
7. Receive
Network Programming Part I 4
27.7 Windows Socket
File Purpose
ws2_32.dll Main WinSock 2 DLL
wsock32.dll For WinSock 1.1 support, 32-bit applications
mswsock.dll MS extensions to WinSock
winsock.dll For WinSock 1.1 support, 16-bit applications
ws2help.dll WinSock2 helper
ws2tcpip.dll WinSock 2 helper for TCP/IP stacks
These files are windows socket libraries.
27.8 WinSock Initialization
The WSAStartup
function initiates use of WS2_32.DLL by a
process.
int WSAStartup(
WORD
wVersionRequested,
/*MAKEWORD(2,2)*/
LPWSADATA
lpWSAData /*POINTER TO THE
WSADATA structure
);wVersionRequested: Highest
version of Windows Sockets support that the caller can use.
The high-order byte specifies the minor version (revision)
number; the low-order byte
specifies the major version number.
lpWSAData: Pointer to the
WSADATA
data structure that is to receive details of the
Windows Sockets implementation.
Return Values: The
WSAStartup
function returns zero if successful. Otherwise, it
returns one of the error codes listed in the following.
An application cannot call
WSAGetLastError
to determine the error code as is
normally done in Windows Sockets if
WSAStartup
fails. The WS2_32.DLL will
not
have been loaded in the case of a failure so the client data
area where the last error
information is stored could not be established.
Error code Meaning
WSASYSNOTREADY Indicates
that the underlying network subsystem is not
ready for network communication.
WSAVERNOTSUPPORTED
The version of Windows Sockets support requested is not
provided by this particular Windows Sockets
implementation.
WSAEINPROGRESS A blocking
Windows Sockets 1.1 operation is in progress.
WSAEPROCLIM Limit on the
number of tasks supported by the Windows
Sockets implementation has been reached.
Network Programming Part I 5
WSAEFAULT The
lpWSAData
is not a valid pointer.
The WSAStartup
function
must
be the first Windows Sockets function called by an
application or DLL. It allows an application or DLL to specify
the version of Windows
Sockets required and retrieve details of the specific Windows
Sockets
implementation. The application or DLL can only issue further
Windows Sockets
functions after successfully calling
WSAStartup.
In order to support future Windows Sockets implementations and
applications that
can have functionality differences from the current version of
Windows Sockets, a
negotiation takes place in
WSAStartup.
The caller of WSAStartup
and the
WS2_32.DLL indicate to each other the highest version that they
can support, and
each confirms that the other's highest version is acceptable.
Upon entry to
WSAStartup, the
WS2_32.DLL examines the version requested by the application.
If this version is equal to or higher than the lowest version
supported by the DLL, the
call succeeds and the DLL returns in
wHighVersion
the highest version it supports
and in wVersion
the minimum of its high version and
wVersionRequested.
The
WS2_32.DLL then assumes that the application will use
wVersion
If the
wVersion
parameter of the
WSADATA structure is unacceptable to
the caller, it should call
WSACleanup and either
search for another WS2_32.DLL or fail to initialize.
It is legal and possible for an application written to this
version of the specification to
successfully negotiate a higher version number version. In that
case, the application
is only guaranteed access to higher-version functionality that
fits within the syntax
defined in this version, such as new Ioctl codes and new
behavior of existing
functions. New functions may be inaccessible. To get full access
to the new syntax of
a future version, the application must fully conform to that
future version, such as
compiling against a new header file, linking to a new ,
or other special cases.
This negotiation allows both a WS2_32.DLL and a Windows Sockets
application to
support a range of Windows Sockets versions. An application can
use WS2_32.DLL if
there is any overlap in the version ranges. The following table
shows how
WSAStartup works with
different applications and WS2_32.DLL versions.
App versions DLL versions
wVersion
requested wVersion wHigh
version End result
1.1 1.1 1.1 1.1 1.1 use 1.1
1.0 1.1 1.0 1.1 1.0 1.0 use 1.0
1.0 1.0 1.1 1.0 1.0 1.1 use 1.0
1.1 1.0 1.1 1.1 1.1 1.1 use 1.1
1.1 1.0 1.1 1.0 1.0 Application fails
1.0 1.1 1.0 --- --- WSAVERNOTSUPPORTED
1.0 1.1 1.0 1.1 1.1 1.1 1.1 use 1.1
1.1 2.0 1.1 2.0 1.1 1.1 use 1.1
2.0 2.0 2.0 2.0 2.0 use 2.0
Network Programming Part I 6
Example Code
The following code fragment demonstrates how an application that
supports only version
2.2 of Windows Sockets makes a
WSAStartup call:
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return;
}
/* 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. */
WSACleanup( );
return;
}
/* The WinSock DLL is acceptable. Proceed. */
Once an application or DLL has made a successful
WSAStartup
call, it can proceed
to make other Windows Sockets calls as needed. When it has
finished using the
services of the WS2_32.DLL, the application or DLL must call
WSACleanup
to allow
the WS2_32.DLL to free any resources for the application.
Details of the actual Windows Sockets implementation are
described in the
WSADATA structure.
An application or DLL can call
WSAStartup
more than once if it needs to obtain the
WSADATA structure
information more than once. On each such call the application
can specify any version number supported by the DLL.
An application must call one
WSACleanup
call for every successful
WSAStartupcall to allow third-party DLLs to make use of a WS2_32.DLL on
behalf of an
application. This means, for example, that if an application
calls WSAStartup
three
times, it must call WSACleanup three times. The first
two calls to WSACleanup
do
nothing except decrement an internal counter; the final
WSACleanup
call for the
task does all necessary resource deallocation for the task.
Network Programming Part I 7
WinSock version: high-order byte specifies the minor version
(revision) number; the loworder
byte specifies the major version number.
Summary
Socket is important in an inter-process communication. Sockets
are more reliable
and secure. Socket version 2 is used these days. In windows,
sockets are started using
WSAStartup API. WSAStartup API starts and initializes Windows
Sockets. Domain
Name System (DNS), the locator service of choice in Microsoft®
Windows®, is an
industry-standard protocol that locates computers on an IP-based
network.
Exercises
1. Study internet protocols by yourself.
Chapter 28
28.1 WINSOCK
SERVER
SOCKET
FUNCTIONS
2
BIND
2
SOCKADDR
4
GETHOSTBYNAME 4
CONNECT
6
28.2 SENDING OR
RECEIVING FROM SERVER 8
SEND
8
RECV
9
28.3 DIFFERENCE
BETWEEN SERVER AND CLIENT SOCKET CALLS
11
28.4 LISTEN
12
28.5 ACCEPT
13
28.6 WINSOCK
EXAMPLE
APPLICATION
14
28.7 EXAMPLE
APPLICATION
14
SUMMARY
17
EXERCISES
17
Network Programming Part II
2
28.1 WinSock Server Socket Functions
Bind:
The bind function
associates a local address with a socket.
int bind(
SOCKET
s, //socket
descriptor */
const struct sockaddr*
name,
/* sockaddr structure */ /*read the
compatibility problem statements by the use of IPv4 and IPv6*/
/*connect Virtual University resource for the updated IPv6
informations*/
int
namelen
);s: Descriptor identifying
an unbound socket.
name: Address to assign to
the socket from the sockaddr
structure.
namelen: Length of the
value in the name
parameter, in bytes.
Return Value: 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.
WSAEACCESAttempt to connect datagram socket to broadcast
address failed because
setsockopt option
SO_BROADCAST is not enabled.
WSAEADDRINUSEA 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.
WSAEFAULTThe 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
Network Programming Part II
3
name does not match the
address family associated
with the socket descriptor
s.
WSAEINPROGRESSA 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.
The bind
function is used on an unconnected socket before
subsequent calls to connector listen
functions. It is used to bind to either connection-oriented (stream) or
connectionless (datagram) 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 addresses.
• 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.
Network Programming Part II
4
Note 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.
Sockaddr
The sockaddr structure varies depending on the protocol
selected. Except for the
sa_family parameter,
sockaddr contents are expressed in network byte order.
In Windows Sockets 2, the
name
parameter is not strictly interpreted as a pointer to a
sockaddr structure. It is presented in this manner for Windows
Sockets compatibility. The
actual structure is interpreted differently in the context of
different address families. The
only requirements are that the first
u_short
is the address family and the total size of the
memory buffer in bytes is
namelen.
The structures below are used with IPv4 and IPv6, respectively.
Other protocols use
similar structures.
struct sockaddr_in {
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct sockaddr_in6 {
short sin6_family;
u_short sin6_port;
u_long sin6_flowinfo;
struct in6_addr sin6_addr;
u_long sin6_scope_id;
};
struct sockaddr_in6_old {
short sin6_family;
u_short sin6_port;
u_long sin6_flowinfo;
struct in6_addr sin6_addr;
};
Host and network byte-ordering: htonl(), htons(), ntohl(),
ntohs()
gethostbynameThe gethostbyname
function retrieves host information corresponding to a host name
from a host database.
struct hostent* FAR gethostbyname(
const char*
name
);Network Programming Part II
5
name: Pointer to the
null-terminated name of the host to resolve.
Return Value: If no error
occurs, gethostbyname
returns a pointer to the
hostent
structure described above. Otherwise, it returns a null pointer
and a specific error number
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.
WSAHOST_NOT_FOUND
Authoritative answer host not found.
WSATRY_AGAIN
Nonauthoritative host not found, or server failure.
WSANO_RECOVERY A
nonrecoverable error occurred.
WSANO_DATA Valid name, no
data record of requested type.
WSAEINPROGRESSA blocking Windows Sockets 1.1 call is in progress,
or the service provider is still processing a callback
function.
WSAEFAULT The
name
parameter is not a valid part of the user
address space.
WSAEINTR A blocking
Windows Socket 1.1 call was canceled
through WSACancelBlockingCall.
The gethostbyname
function returns a pointer to a
hostent
structure—a structure
allocated by Windows Sockets. The
hostent
structure contains the results of a successful
search for the host specified in the
name
parameter.
The application must never attempt to modify this structure or
to free any of its
components. Furthermore, only one copy of this structure is
allocated per thread, so the
application should copy any information it needs before issuing
any other Windows
Sockets function calls.
The gethostbyname
function cannot resolve IP address strings passed to it. Such a
request is treated exactly as if an unknown host name were
passed. Use inet_addr to
convert an IP address string the string to an actual IP address,
then use another function,
gethostbyaddr, to obtain
the contents of the hostent
structure.
If null is provided in the
name
parameter, the returned string is the same as the string
returned by a successful
gethostname function call.
Note The
gethostbyname function does not check the size of the name parameter before
passing the buffer. In improperly sized name parameters, heap
corruption can occur.
Network Programming Part II
6
ConnectThe connect
function establishes a connection to a specified socket.
int connect(
SOCKET
s,
const struct sockaddr*
name,
int
namelen
);s: Descriptor identifying
an unconnected socket.
name: Name of the socket
in the sockaddr
structure to which the connection should be
established.
namelen: Length of
name,
in bytes
Return Values: If no error
occurs, connect
returns zero. Otherwise, it returns
SOCKET_ERROR, and a specific error code can be retrieved by
calling
WSAGetLastError.
On a blocking socket, the return value indicates success or
failure of the connection
attempt.
With a nonblocking socket, the connection attempt cannot be
completed immediately. In
this case, connect
will return SOCKET_ERROR, and
WSAGetLastError
will return
WSAEWOULDBLOCK. In this case, there are three possible
scenarios:
Use the
select
function to determine the completion of the connection request by
checking to see if the socket is writeable.
If the application is using
WSAAsyncSelect
to indicate interest in connection
events, then the application will receive an FD_CONNECT
notification indicating
that the connect
operation is complete (successfully or not).
If the application is using
WSAEventSelect
to indicate interest in connection
events, then the associated event object will be signaled
indicating that the
connect operation is
complete (successfully or not).
Until the connection attempt completes on a nonblocking socket,
all subsequent calls to
connect on the same socket
will fail with the error code WSAEALREADY, and
WSAEISCONN when the connection completes successfully. Due to
ambiguities in
version 1.1 of the Windows Sockets specification, error codes
returned from
connectwhile a connection is already pending may vary among
implementations. As a result, it is
not recommended that applications use multiple calls to connect
to detect connection
completion. If they do, they must be prepared to handle
WSAEINVAL and
WSAEWOULDBLOCK error values the same way that they handle
WSAEALREADY,
to assure robust execution.
Network Programming Part II
7
The connect
function is used to create a connection to the specified destination. If socket
s, is unbound, unique
values are assigned to the local association by the system, and the
socket is marked as bound.
For connection-oriented sockets (for example, type SOCK_STREAM),
an active
connection is initiated to the foreign host using
name
(an address in the namespace of the
socket.
Note:
If a socket
is opened, a setsockopt
call is made, and then a
sendto
call is made,
Windows Sockets performs an implicit
bind
function call.
When the socket call completes successfully, the socket is ready
to send and receive data.
If the address member of the structure specified by the
name parameter is all zeroes,
connect will return the
error WSAEADDRNOTAVAIL. Any attempt to reconnect an
active connection will fail with the error code WSAEISCONN.
For connection-oriented, nonblocking sockets, it is often not
possible to complete the
connection immediately. In such a case, this function returns
the error
WSAEWOULDBLOCK. However, the operation proceeds.
When the success or failure outcome becomes known, it may be
reported in one of two
ways, depending on how the client registers for notification.
If the client uses the
select
function, success is reported in the writefds set and
failure is reported in the exceptfds set.
If the client uses the
functions WSAAsyncSelect
or
WSAEventSelect, the
notification is announced with FD_CONNECT and the error code
associated
with the FD_CONNECT indicates either success or a specific
reason for
failure.
For a connectionless socket (for example, type SOCK_DGRAM), the
operation
performed by connect
is merely to establish a default
destination address that can be used
on subsequent send/
WSASend
and recv/
WSARecv
calls. Any datagrams received from
an address other than the destination address specified will be
discarded. If the address
member of the structure specified by
name
is all zeroes, the socket will be disconnected.
Then, the default remote address will be indeterminate, so
send/
WSASend
and recv/
WSARecv calls will return
the error code WSAENOTCONN. However,
sendto/
WSASendTo and
recvfrom/
WSARecvFrom
can still be used. The default destination
can be changed by simply calling
connect
again, even if the socket is already connected.
Any datagrams queued for receipt are discarded if
name
is different from the previous
connect.
For connectionless sockets,
name
can indicate any valid address, including a broadcast
address. However, to connect to a broadcast address, a socket
must use setsockopt
to
enable the SO_BROADCAST option. Otherwise,
connect
will fail with the error code
WSAEACCES.
Network Programming Part II
8
When a connection between sockets is broken, the sockets should
be discarded and
recreated. When a problem develops on a connected socket, the
application must discard
and recreate the needed sockets in order to return to a stable
point.
28.2 Sending or receiving from server
Send
The send function
sends data on a connected socket.
int send(
SOCKET
s,
const char*
buf,
int
len,
int
flags
);s: Descriptor identifying
a connected socket.
buf: Buffer containing the
data to be transmitted.
len: Length of the data in
buf,
in bytes
flags: Indicator
specifying the way in which the call is made.
Return Values: If no error
occurs, send
returns the total number of bytes sent, which can
be less than the number indicated by
len.
Otherwise, a value of SOCKET_ERROR is
returned
The send
function is used to write outgoing data on a
connected socket. For messageoriented
sockets, care must be taken not to exceed the maximum packet
size of the
underlying provider, which can be obtained by using
getsockopt
to retrieve the value of
socket option SO_MAX_MSG_SIZE. If the data is too long to pass
atomically through
the underlying protocol, the error WSAEMSGSIZE is returned, and
no data is
transmitted.
The successful completion of a
send
does not indicate that the data was successfully
delivered.
If no buffer space is available within the transport system to
hold the data to be
transmitted, send
will block unless the socket has been placed
in nonblocking mode. On
nonblocking stream oriented sockets, the number of bytes written
can be between 1 and
the requested length, depending on buffer availability on both
client and server
computers. The select,
WSAAsyncSelect
or
WSAEventSelect functions can be used to
determine when it is possible to send more data.
Calling send
with a zero
len
parameter is permissible and will be treated by
implementations as successful. In such cases,
send
will return zero as a valid value. For
message-oriented sockets, a zero-length transport datagram is
sent.
Network Programming Part II
9
The flags
parameter can be used to influence the behavior of the function beyond the
options specified for the associated socket. The semantics of
this function are determined
by the socket options and the
flags parameter. The latter is constructed by using the
bitwise OR operator with any of the following values.
Value Meaning
MSG_DONTROUTE Specifies that the data should not be subject to
routing. A
Windows Sockets service provider can choose to ignore this flag.
MSG_OOB
Sends OOB data (stream-style socket such as SOCK_STREAM
only. Also see DECnet Out-Of-band data for a discussion of this
topic).
RecvThe recv function
receives data from a connected or bound socket.
int recv(
SOCKET
s,
char*
buf,
int
len,
int
flags
);s: Descriptor identifying
a connected socket.
buf: Buffer for the
incoming data.
len: Length of
buf,
in bytes
flags: Flag specifying the
way in which the call is made.
Return Values: If no error
occurs, recv
returns the number of bytes received. If the
connection has been gracefully closed, the return value is zero.
Otherwise, a value of
SOCKET_ERROR is returned,
The recv
function is used to read incoming data on
connection-oriented sockets, or
connectionless sockets. When using a connection-oriented
protocol, the sockets must be
connected before calling
recv. When using a connectionless
protocol, the sockets must be
bound before calling
recv.
The local address of the socket must be known. For server
applications, use an explicit
bind function or an
implicit accept
or
WSAAccept function. Explicit binding is
discouraged for client applications. For client applications,
the socket can become bound
implicitly to a local address using
connect,
WSAConnect,
sendto,
WSASendTo,
or
WSAJoinLeaf.
For connected or connectionless sockets, the
recv
function restricts the addresses from
which received messages are accepted. The function only returns
messages from the
Network Programming Part II
10
remote address specified in the connection. Messages from other
addresses are (silently)
discarded.
For connection-oriented sockets (type SOCK_STREAM for example),
calling recv will
return as much information as is currently available—up to the
size of the buffer
specified. If the socket has been configured for in-line
reception of OOB data (socket
option SO_OOBINLINE) and OOB data is yet unread, only OOB data
will be returned.
The application can use the
ioctlsocket or WSAIoctl SIOCATMARK
command to
determine whether any more OOB data remains to be read.
For connectionless sockets (type SOCK_DGRAM or other
message-oriented sockets),
data is extracted from the first enqueued datagram (message)
from the destination address
specified by the connect
function.
If the datagram or message is larger than the buffer specified,
the buffer is filled with the
first part of the datagram, and
recv generates the error WSAEMSGSIZE. For unreliable
protocols (for example, UDP) the excess data is lost; for
reliable protocols, the data is
retained by the service provider until it is successfully read
by calling recv with a large
enough buffer.
If the socket is connection oriented and the remote side has
shut down the connection
gracefully, and all data has been received, a
recv will complete immediately
with zero
bytes received. If the connection has been reset, a
recv will fail with the error
WSAECONNRESET.
The flags
parameter can be used to influence the behavior of the function invocation
beyond the options specified for the associated socket. The
semantics of this function are
determined by the socket options and the
flags parameter. The latter is
constructed by
using the bitwise OR operator with any of the following values.
Value Meaning
MSG_PEEK
Peeks at the incoming data. The data is copied into the buffer
but is not
removed from the input queue. The function subsequently returns
the
amount of data that can be read in a single call to the
recv (or
recvfrom)
function, which may not be the same as the total amount of data
queued on
the socket. The amount of data that can actually be read in a
single call to
the recv (or
recvfrom) function is limited to
the data size written in the
send or
sendto
function call.
MSG_OOB Processes OOB data. (See DECnet Out-of-band data for a
discussion of this
topic.)
Network Programming Part II
11
28.3 Difference between server and client socket calls
Figure 1 Client Connection
Socket()
Connect()
Send/recv()
closesocket
Socket()
bind()
Listen()
accept
Recv/send
closesocket
Network Programming Part II
12
Figure 2 Server Connection
28.4 Listen
The listen
function places a socket in a state in which it is listening for an incoming
connection.
int listen(
SOCKET
s,
int
backlog
);s: Descriptor identifying
a bound, unconnected socket.
Backlog: Maximum length of
the queue of pending connections. If set to
SOMAXCONN, the underlying service provider responsible for
socket s
will set the
backlog to a maximum reasonable value. There is no standard
provision to obtain the
actual backlog value.
Return Values: If no error
occurs, listen
returns zero. Otherwise, a value of
SOCKET_ERROR is returned.
To accept connections, a socket is first created with the
socket
function and bound to a
local address with the
bind function, a backlog for incoming
connections is specified
with listen, and then the connections are accepted with the
accept
function. Sockets that
are connection oriented those of type SOCK_STREAM for example,
are used with listen.
The socket s
is put into passive mode where incoming
connection requests are
acknowledged and queued pending acceptance by the process.
The listen
function is typically used by servers that can have
more than one connection
request at a time. If a connection request arrives and the queue
is full, the client will
receive an error with an indication of WSAECONNREFUSED.
If there are no available socket descriptors,
listen
attempts to continue to function. If
descriptors become available, a later call to
listen
or accept
will refill the queue to the
current or most recent backlog, if possible, and resume
listening for incoming
connections.
An application can call
listen more than once on the same
socket. This has the effect of
updating the current backlog for the listening socket. Should
there be more pending
connections than the new backlog value, the excess pending
connections will be reset and
dropped.
Network Programming Part II
13
28.5 Accept
The accept
function permits an incoming connection attempt on a socket.
SOCKET accept(
SOCKET
s, /*socket
descriptor*/
struct sockaddr*
addr,
/*sockaddr structure*/
int*
addrlen /*string length returned*/
);s: Descriptor identifying
a socket that has been placed in a listening state with the
listen
function. The connection is actually made with the socket that
is returned by accept.
addr: Optional pointer to
a buffer that receives the address of the connecting entity, as
known to the communications layer. The exact format of the
addr
parameter is
determined by the address family that was established when the
socket from the
sockaddr structure was
created.
Addrlen: Optional pointer
to an integer that contains the length of
addr.
Return Values: If no error
occurs, accept
returns a value of type
SOCKET
that is a
descriptor for the new socket. This returned value is a handle
for the socket on which the
actual connection is made. Otherwise, a value of INVALID_SOCKET
is returned
The accept
function extracts the first connection on the queue
of pending connections on
socket s.
It then creates and returns a handle to the new socket. The newly created socket
is the socket that will handle the actual connection; it has the
same properties as socket s,
including the asynchronous events registered with the
WSAAsyncSelect
or
WSAEventSelect functions.
The accept
function can block the caller until a connection is
present if no pending
connections are present on the queue, and the socket is marked
as blocking. If the socket
is marked as nonblocking and no pending connections are present
on the queue, acceptreturns an error as described in the following. After the
successful completion of accept
returns a new socket handle, the accepted socket cannot be used
to accept more
connections. The original socket remains open and listens for
new connection requests.
The parameter addr
is a result parameter that is filled in with the address of the
connecting entity, as known to the communications layer. The
exact format of the addr
parameter is determined by the address family in which the
communication is occurring.
The addrlen is a
value-result parameter; it should initially contain the amount of space
pointed to by addr;
on return it will contain the actual length (in bytes) of the address
returned.
The accept
function is used with connection-oriented socket types such as
SOCK_STREAM. If addr
and/or addrlen are equal
to NULL, then no information about
the remote address of the accepted socket is returned.
Network Programming Part II
14
28.6 WinSock Example Application
A client showing simple communication to either our own small
server, or some server
on the internet, e.g. WHOIS servers, HTTP server, time service
etc.
A small utility that synchronizes system time with a source on
the internet, accounting for
transmission-delays
Screen shot of our application.
28.7 Example Application
Int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR
lpCmdLine, int nCmdShow)
{
WSADATA wsaData;
HOSTENT *ptrHostEnt;
struct sockaddr_in serverSockAddr; // the address of the socket
to connect to
int abc;
// try initialising the windows sockets
if(WSAStartup( MAKEWORD(1,1), &wsaData)) // request WinSock ver
1.1
{
MessageBox(NULL, "Error initialising sockets .", "WinSock
Error", MB_OK | MB_ICONSTOP);
return 1;
}
/*Get host name */Network Programming Part II
15
if(!(ptrHostEnt = gethostbyname(WHOIS_SERVER_NAME)))
{
MessageBox(NULL, "Could not resolve WHOIS server name.",
"WinSock Error", MB_OK | MB_ICONSTOP);
WSACleanup();
return 1;
}
serverSockAddr.sin_family = AF_INET; // fill the address
structure with appropriate
values
serverSockAddr.sin_port = htons(WHOIS_PORT); // MUST convert to
network
byte-order
memset(serverSockAddr.sin_zero, 0,
sizeof(serverSockAddr.sin_zero));
memcpy(&serverSockAddr.sin_addr.S_un.S_addr,
ptrHostEnt->h_addr_list[0],
sizeof(unsigned long));
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(clientSocket == INVALID_SOCKET)
{
MessageBox(NULL, "Error creating client socket.", "WinSock
Error",
MB_OK | MB_ICONSTOP);
WSACleanup();
return 1;
}
/*Start Connection*/
if(connect(clientSocket, (struct sockaddr *)&serverSockAddr,
sizeof(serverSockAddr)))
{
abc = WSAGetLastError();
MessageBox(NULL, "Error connecting to WHOIS server.", "WinSock
Error", MB_OK | MB_ICONSTOP);
WSACleanup();
return 1;
}
if(DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG_MAIN),
NULL, mainDialogProc) == 1)
MessageBox(NULL, "Error occurred while sending data to WHOIS
server.", "WinSock Error", MB_OK | MB_ICONSTOP);
WSACleanup();
return 0;
Network Programming Part II
16
}
BOOL CALLBACK mainDialogProc(HWND hDlg, UINT message, WPARAM
wParam, LPARAM lParam)
{
int wID, wNotificationCode;
char domainName[MAX_DOMAIN_LEN+2+1]; // accomodate CR/LF/NULL
char result[BUFFER_SIZE], *startOfBuffer = result;
int bytesReceived;
switch(message)
{
case WM_INITDIALOG:
SendDlgItemMessage(hDlg, IDC_EDIT_DOMAIN, EM_LIMITTEXT,
MAX_DOMAIN_LEN, 0);
return TRUE;
break;
case WM_COMMAND:
wNotificationCode = HIWORD(wParam);
wID = LOWORD(wParam);
switch(wID)
{
case IDC_BUTTON_SEND:
EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_SEND),
FALSE); // disable for 2nd use
GetDlgItemText(hDlg, IDC_EDIT_DOMAIN,
(LPSTR)domainName, MAX_DOMAIN_LEN+1);
strcpy(domainName+strlen(domainName), "\r\n");
if(send(clientSocket, (const char *)domainName,
strlen(domainName), 0) == SOCKET_ERROR)
EndDialog(hDlg, 1);
else
{
bytesReceived = recv(clientSocket, startOfBuffer,
BUFFER_SIZE-1, 0); // -1 for NULL
while(bytesReceived > 0)// 0:close
//SOCKET_ERROR:error
{
startOfBuffer += bytesReceived; //
//move it forward
bytesReceived = recv(clientSocket, startOfBuffer,
BUFFER_SIZE-(startOfBuffer-result)-1, 0); // -1 for NULL
}
Network Programming Part II
17
if(startOfBuffer != result) // something received
*startOfBuffer = NULL; // NULL terminate
else
strcpy(result, "Null Response");
SetDlgItemText(hDlg, IDC_EDIT_RESULT, result);
}
break;
case IDCANCEL:
EndDialog(hDlg, 0);
break;
}
return TRUE;
break;
default:
return FALSE;
}
return TRUE;
}
Summary
In this lecture, we studied about WinSock functions. These
functions include
connect, recv, send, accept, bind, gethotbyname, etc. we saw the
difference between
client socket connection and server socket connection. And
finally we made application
that is whoisserver. This application tells that the name is
registered name or not. If the
name is registered, then we cannot register it again.
Note: These lectures explain only IPv4, this protocol is being
replaced by IPv6. New
resource should use IPv6. For New Internet Protocol version and
programming using
IPv6, connect to Virtual University resource online.
Exercises
1. Create a simple socket client server application that uses
stream socket and
TCP/IP protocols. On connecting, the client server must show
message that client
has been connected. |