Previous | Contents | Index |
Make the following calls to close and delete a socket:
Example 2-27 shows a TCP application using OpenVMS system services to close and delete a socket.
Example 2-27 Closing and Deleting a Socket (System Services) |
---|
#include <descrip.h> /* define OpenVMS descriptors */ #include <efndef.h> /* define 'EFN$C_ENF' event flag */ #include <iodef.h> /* define i/o function codes */ #include <ssdef.h> /* define system service status codes */ #include <starlet.h> /* define system service calls */ #include <stdio.h> /* define standard i/o functions */ #include <stdlib.h> /* define standard library functions */ #include <stsdef.h> /* define condition value fields */ #include <tcpip$inetdef.h> /* define tcp/ip network constants, */ /* structures, and functions */ struct iosb { /* i/o status block */ unsigned short status; /* i/o completion status */ unsigned short bytcnt; /* bytes transferred if read/write */ void *details; /* address of buffer or parameter */ }; struct sockchar { /* socket characteristics */ unsigned short prot; /* protocol */ unsigned char type; /* type */ unsigned char af; /* address format */ }; int main( void ) { struct iosb iosb; /* i/o status block */ unsigned int status; /* system service return status */ unsigned short channel; /* network device i/o channel */ struct sockchar sockchar; /* socket characteristics buffer */ $DESCRIPTOR( inet_device, /* string descriptor with logical */ "TCPIP$DEVICE:" ); /* name of network pseudodevice */ /* * initialize socket characteristics */ sockchar.prot = TCPIP$C_TCP; sockchar.type = TCPIP$C_STREAM; sockchar.af = TCPIP$C_AF_INET; /* * assign i/o channel to network device */ status = sys$assign( &inet_device, /* device name */ &channel, /* i/o channel */ 0, /* access mode */ 0 /* not used */ ); if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to assign i/o channel\n" ); exit( status ); } /* * create a socket */ status = sys$qiow( EFN$C_ENF, /* event flag */ channel, /* i/o channel */ IO$_SETMODE, /* i/o function code */ &iosb, /* i/o status block */ 0, /* ast service routine */ 0, /* ast parameter */ &sockchar, /* p1 - socket characteristics */ 0, /* p2 */ 0, /* p3 */ 0, /* p4 */ 0, /* p5 */ 0 /* p6 */ ); if ( status & STS$M_SUCCESS ) status = iosb.status; if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to create socket\n" ); exit( status ); } /* * close socket */ status = sys$qiow( EFN$C_ENF, /* event flag */ channel, /* i/o channel */ IO$_DEACCESS, /* i/o function code */ &iosb, /* i/o status block */ 0, /* ast service routine */ 0, /* ast parameter */ 0, /* p1 */ 0, /* p2 */ 0, /* p3 */ 0, /* p4 */ 0, /* p5 */ 0 /* p6 */ ); if ( status & STS$M_SUCCESS ) status = iosb.status; if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to close socket\n" ); exit( status ); } /* * deassign i/o channel to network device */ status = sys$dassgn( channel ); if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to deassign i/o channel\n" ); exit( status ); } exit( EXIT_SUCCESS ); } |
You can shut down a socket before closing and deleting it. The shutdown
operation allows you to shut down communication one process at a time.
This maintains unidirectional rather than the normal bidirectional
connections, allowing you to shut down communications on receive or
transmit data queues, or both. For example, if you no longer want to
transmit data but want to continue receiving data, shut down the
transmit side of the socket connection and keep open the receive side.
2.18.1 Shutting Down a Socket (Sockets API)
Example 2-28 shows a TCP application using the shutdown() function.
Example 2-28 Shutting Down a Socket (Sockets API) |
---|
#include <socket.h> /* define BSD socket api */ #include <stdio.h> /* define standard i/o functions */ #include <stdlib.h> /* define standard library functions */ #include <unixio.h> /* define unix i/o */ int main( void ) { int sockfd; /* * create a socket */ if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { perror( "Failed to create socket" ); exit( EXIT_FAILURE ); } /* * shutdown a socket */ if ( shutdown(sockfd,(1) 2 (2)) < 0 ) { perror( "Failed to shutdown socket connections" ); exit( EXIT_FAILURE ); } /* * close socket */ if ( close(sockfd) < 0 ) { perror( "Failed to close socket" ); exit( EXIT_FAILURE ); } exit( EXIT_SUCCESS ); } |
To shut down a socket, use the IO$_DEACCESS function with the IO$M_SHUTDOWN function modifier. This function shuts down all or part of the full-duplex connection on the socket.
The application uses subfunctions or flags to specify whether pending I/O operations are completed or discarded before the IO$_DEACCESS function completes. After the IO$_DEACCESS function completes, messages can no longer be transmitted or received.
Example 2-29 shows a TCP server using the IO$_DEACCESS function with the IO$M_SHUTDOWN function modifier to shut down all communications. In this example, no data is received or transmitted and all queued data is discarded.
Example 2-29 Shutting Down a Socket (System Services) |
---|
#include <descrip.h> /* define OpenVMS descriptors */ #include <efndef.h> /* define 'EFN$C_ENF' event flag */ #include <iodef.h> /* define i/o function codes */ #include <ssdef.h> /* define system service status codes */ #include <starlet.h> /* define system service calls */ #include <stdio.h> /* define standard i/o functions */ #include <stdlib.h> /* define standard library functions */ #include <stsdef.h> /* define condition value fields */ #include <tcpip$inetdef.h> /* define tcp/ip network constants, */ /* structures, and functions */ struct iosb { /* i/o status block */ unsigned short status; /* i/o completion status */ unsigned short bytcnt; /* bytes transferred if read/write */ void *details; /* address of buffer or parameter */ }; struct sockchar { /* socket characteristics */ unsigned short prot; /* protocol */ unsigned char type; /* type */ unsigned char af; /* address format */ }; int main( void ) { struct iosb iosb; /* i/o status block */ unsigned int status; /* system service return status */ unsigned short channel; /* network device i/o channel */ struct sockchar sockchar; /* socket characteristics buffer */ $DESCRIPTOR( inet_device, /* string descriptor with logical */ "TCPIP$DEVICE:" ); /* name of network pseudodevice */ /* * initialize socket characteristics */ sockchar.prot = TCPIP$C_TCP; sockchar.type = TCPIP$C_STREAM; sockchar.af = TCPIP$C_AF_INET; /* * assign i/o channel to network device */ status = sys$assign( &inet_device, /* device name */ &channel, /* i/o channel */ 0, /* access mode */ 0 /* not used */ ); if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to assign i/o channel\n" ); exit( status ); } /* * create a socket */ status = sys$qiow( EFN$C_ENF, /* event flag */ channel, /* i/o channel */ IO$_SETMODE, /* i/o function code */ &iosb, /* i/o status block */ 0, /* ast service routine */ 0, /* ast parameter */ &sockchar, /* p1 - socket characteristics */ 0, /* p2 */ 0, /* p3 */ 0, /* p4 */ 0, /* p5 */ 0 /* p6 */ ); if ( status & STS$M_SUCCESS ) status = iosb.status; if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to create socket\n" ); exit( status ); } /* * shutdown a socket */ status = sys$qiow( EFN$C_ENF, /* event flag */ channel, /* i/o channel */ IO$_DEACCESS|IO$M_SHUTDOWN, /* i/o function code */ &iosb, /* i/o status block */ 0, /* ast service routine */ 0, /* ast parameter */ 0, /* p1 */ 0, /* p2 */ 0, /* p3 */ TCPIP$C_DSC_ALL, /* p4 - discard all packets */ 0, /* p5 */ 0 /* p6 */ ); if ( status & STS$M_SUCCESS ) status = iosb.status; if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to shutdown socket connections\n" ); exit( status ); } /* * close socket */ status = sys$qiow( EFN$C_ENF, /* event flag */ channel, /* i/o channel */ IO$_DEACCESS, /* i/o function code */ &iosb, /* i/o status block */ 0, /* ast service routine */ 0, /* ast parameter */ 0, /* p1 */ 0, /* p2 */ 0, /* p3 */ 0, /* p4 */ 0, /* p5 */ 0 /* p6 */ ); if ( status & STS$M_SUCCESS ) status = iosb.status; if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to close socket\n" ); exit( status ); } /* * deassign i/o channel to network device */ status = sys$dassgn( channel ); if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to deassign i/o channel\n" ); exit( status ); } exit( EXIT_SUCCESS ); } |
The $CANCEL system service cancels pending I/O requests on a specific channel or socket. This includes all I/O requests queued and in progress.
There is no Sockets API function for this operation; the Sockets API library functions are synchronous.
This chapter contains information to help you increase the portability
of the network application programs that you write using the
TCP/IP Services implementation of the Sockets API.
3.1 Internet Protocols
The IP (Internet Protocol) family is a collection of protocols on the
Transport layer that use the internet address format. This section
describes TCP (Transmission Control Protocol) and UDP (User Datagram
Protocol) sockets.
3.1.1 TCP Sockets
TCP provides reliable, flow-controlled, two-way transmission of data. A byte-stream protocol used to support the SOCK_STREAM abstraction, TCP uses the standard IP address format and provides a per-host collection of port addresses. Thus, each address consists of an internet address specifying the host and network, with a specific TCP port on the host identifying the peer entity.
Sockets using TCP are either active or passive, as described in Table 3-1.
Active sockets use the connect() function to initiate connections.)
Socket Type | Description |
---|---|
Active | Initiates connections to passive sockets. By default, TCP sockets are active. |
Passive |
Listens for connection requests from active sockets. To create a
passive socket, use the
bind()
function and then the
listen()
function.
Passive sockets use the accept() function to accept incoming connections. If the server is running on a multihomed system, you can specify wildcard addressing. Wildcard addressing allows a single server to provide service to clients on multiple networks. (See Section 3.1.1.1.) |
When a server is running on a host that has more than one network interface installed, you can use wildcard addressing to configure it to accept incoming connections on all the interfaces.
The wildcard address is the any-interface choice. You specify this address by setting the IP address in the socket address structure to INADDR_ANY before calling the bind() function.
To create a socket that listens to all hosts on any network interface, perform these steps:
The address assigned to the socket is the address associated with the network interface through which packets from the peer are being transmitted and received. This address corresponds to the peer entity's network.
TCP supports the setting of socket options with the setsockopt() function and the checking of current option settings with the getsockopt function. Under most circumstances, TCP sends data when it is presented. When outstanding data has not been acknowledged, TCP gathers small amounts of output and sends it in a single packet when an acknowledgment is received.
For a small number of clients, such as window systems that send a
stream of mouse events that receive no replies, this packetization can
cause significant delays. Therefore, TCP provides a Boolean option,
TCP_NODELAY
(from TCP.H), to defeat this algorithm. The option level for the
setsockopt()
function is the protocol number for TCP, which is available from
getprotobyname()
. In this situation, servers may want to use
TCP_NODELAY
; however, network traffic may increase significantly as a result.
3.1.2 UDP Sockets
UDP is a protocol that supports the SOCK_DGRAM abstraction for the internet protocol family. UDP sockets are connectionless and are normally used with the sendto() and recvfrom() functions. You can also use the connect() function to establish the destination address for future datagrams; then you use the read() , write() , send() , rec() , or recv() function to transmit or receive datagrams.
UDP address formats are identical to those used by TCP. In particular,
UDP provides a port identifier in addition to the normal internet
address format. Note that the UDP port space is separate from the TCP
port space (for example, a UDP port cannot be connected to a TCP port).
Also, you can send broadcast packets (assuming the underlying network
supports this) by using a reserved broadcast address. This address is
network-interface dependent. The
SO_BROADCAST
option must be set on the socket, and the process must have a
privileged UIC or the SYSPRV, BYPASS, or OPER privilege for
broadcasting to succeed.
3.2 Structures
This section describes, in alphabetical order, the structures you supply as arguments to the various Sockets API functions. Table 3-2 lists these structures.
Structure | Description |
---|---|
hostent | This structure holds a canonical host name, alias names, a host address type, the length of the address, and a pointer to a list of host addresses. This structure is a parameter value for host name and address lookup functions. |
in_addr | This structure holds a 32-bit IPv4 address stored in network byte order. |
iovec | This structure holds the beginning address and length of an I/O buffer. |
linger | This structure holds option information for the close function. |
msghdr | This structure holds the protocol address, the size of the protocol address, a scatter-and-gather array, the number of elements in the scatter-and-gather array, ancillary data, the length of the ancillary data, and returned flags. The structure is a parameter of the recvmsg() and sendmsg() functions. |
netent | This structure holds a network name, a list of aliases associated with the network, and the network number. |
sockaddr | The socket functions use this generic socket address structure to function with any of the supported protocol families. |
sockaddr_in | This IPv4 socket address structure holds the length of the structure, the address family, either a TCP or a UDP port number, and a 32-bit IPv4 address stored in network byte order. The structure has a fixed length of 16 bytes. |
timeval | This structure holds a time interval specified in seconds and microseconds. |
Previous | Next | Contents | Index |