Previous | Contents | Index |
Binding a socket associates a local protocol address (that is, a 32-bit IPv4 address and a 16-bit TCP or UDP port number) with a socket. To bind a socket, specify a local interface address and local port number for the socket.
With the TCP protocol, you can specify an IP address, a port number, both an IP address and port number or neither.
If the application is using the UDP protocol and needs to receive
incoming multicast or broadcast datagrams destined for a specific UDP
port, see Section 2.10 for information about specifying the
SO_REUSEPORT option when binding the socket.
2.3.1 Binding a Socket (Sockets API)
Example 2-3 shows an example of a TCP application using the bind() function to bind a socket name.
The process must have a system user identification code (UIC) and the SYSPRV, BYPASS, or OPER privilege to bind port numbers 1 to 1023. |
Example 2-3 Binding a Socket (Sockets API) |
---|
#include <in.h> /* define internet related constants, */ /* functions, and structures */ #include <socket.h> /* define BSD socket api */ #include <stdio.h> /* define standard i/o functions */ #include <stdlib.h> /* define standard library functions */ #include <string.h> /* define string handling functions */ #define PORTNUM 12345 /* server port number */ int main( void ) { int sockfd; struct sockaddr_in addr; /* * initialize socket address structure */ memset( &addr, 0, sizeof(addr) ); addr.sin_family = AF_INET; addr.sin_port = htons( PORTNUM ); addr.sin_addr.s_addr = INADDR_ANY; /* * create a socket */ if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { perror( "Failed to create socket" ); exit( EXIT_FAILURE ); } /* * bind ip address and port number to socket */ if ( bind(sockfd,(1) (struct sockaddr *) &addr,(2) sizeof(addr)(3) ) < 0 ) { perror( "Failed to bind socket" ); exit( EXIT_FAILURE ); } exit( EXIT_SUCCESS ); } |
In this example, the bind() function:
Use the IO$_SETMODE or IO$_SETCHAR function of the $QIO system service to bind a socket.
The process must have a system user identification code (UIC), SYSPRV, BYPASS, or OPER privileges to bind port numbers 1 to 1023. |
Example 2-4 shows a TCP server using the IO$_SETMODE function to bind sockets.
Example 2-4 Binding a Socket (System Services) |
---|
#include <descrip.h> /* define OpenVMS descriptors */ #include <efndef.h> /* define 'EFN$C_ENF' event flag */ #include <in.h> /* define internet related constants, */ /* functions, and structures */ #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 <string.h> /* define string handling functions */ #include <stsdef.h> /* define condition value fields */ #include <tcpip$inetdef.h> /* define tcp/ip network constants, */ /* structures, and functions */ #define PORTNUM 12345 /* server port number */ 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 itemlst_2 { /* item-list 2 descriptor/element */ unsigned short length; /* length */ unsigned short type; /* parameter type */ void *address; /* address of item list */ }; 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 */ struct sockaddr_in addr; /* socket address structure */ struct itemlst_2 addr_itemlst; /* socket address item-list */ $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; /* * initialize socket address item-list descriptor */ addr_itemlst.length = sizeof( addr ); addr_itemlst.type = TCPIP$C_SOCK_NAME; addr_itemlst.address = &addr; /* * initialize socket address structure */ memset( &addr, 0, sizeof(addr) ); addr.sin_family = TCPIP$C_AF_INET; addr.sin_port = htons( PORTNUM ); addr.sin_addr.s_addr = TCPIP$C_INADDR_ANY; /* * 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 ); } /* * bind ip address and port number to 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 */ 0, /* p1 */ 0, /* p2 */ &addr_itemlst, /* p3 - local socket name */ 0, /* p4 */ 0, /* p5 */ 0 /* p6 */ ); if ( status & STS$M_SUCCESS ) status = iosb.status; if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to bind socket\n" ); exit( status ); } exit( EXIT_SUCCESS ); } |
Only server programs that use the TCP protocol need to set a socket to be a listener. This allows the program to receive incoming connection requests. As a connection-oriented protocol, TCP requires a connection; UDP, a connectionless protocol, does not.
The listen() function:
Example 2-5 shows how a TCP server uses the listen() function to set a socket to listen for connection requests and to specify the number of incoming requests that can wait to be queued for processing.
Example 2-5 Setting a Socket to Listen (Sockets API) |
---|
#include <in.h> /* define internet related constants, */ /* functions, and structures */ #include <socket.h> /* define BSD socket api */ #include <stdio.h> /* define standard i/o functions */ #include <stdlib.h> /* define standard library functions */ #include <string.h> /* define string handling functions */ #define BACKLOG 1 /* server backlog */ #define PORTNUM 12345 /* server port number */ int main( void ) { int sockfd; struct sockaddr_in addr; /* * initialize socket address structure */ memset( &addr, 0, sizeof(addr) ); addr.sin_family = AF_INET; addr.sin_port = htons( PORTNUM ); addr.sin_addr.s_addr = INADDR_ANY; /* * create a socket */ if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { perror( "Failed to create socket" ); exit( EXIT_FAILURE ); } /* * bind ip address and port number to socket */ if ( bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0 ) { perror( "Failed to bind socket" ); exit( EXIT_FAILURE ); } /* * set socket as a listen socket */ if ( listen(sockfd, (1) BACKLOG (2) ) < 0 ) { perror( "Failed to set socket passive" ); exit( EXIT_FAILURE ); } exit( EXIT_SUCCESS ); } |
In this example of a listen() function:
Example 2-6 shows how to use the IO$_SETMODE function to set the socket to listen for requests.
Example 2-6 Setting a Socket to Listen (System Services) |
---|
#include <descrip.h> /* define OpenVMS descriptors */ #include <efndef.h> /* define 'EFN$C_ENF' event flag */ #include <in.h> /* define internet related constants, */ /* functions, and structures */ #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 <string.h> /* define string handling functions */ #include <stsdef.h> /* define condition value fields */ #include <tcpip$inetdef.h> /* define tcp/ip network constants, */ /* structures, and functions */ #define BACKLOG 1 /* server backlog */ #define PORTNUM 12345 /* server port number */ 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 itemlst_2 { /* item-list 2 descriptor/element */ unsigned short length; /* length */ unsigned short type; /* parameter type */ void *address; /* address of item list */ }; 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 */ struct sockaddr_in addr; /* socket address structure */ struct itemlst_2 addr_itemlst; /* socket address item-list */ $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; /* * initialize socket address item-list descriptor */ addr_itemlst.length = sizeof( addr ); addr_itemlst.type = TCPIP$C_SOCK_NAME; addr_itemlst.address = &addr; /* * initialize socket address structure */ memset( &addr, 0, sizeof(addr) ); addr.sin_family = TCPIP$C_AF_INET; addr.sin_port = htons( PORTNUM ); addr.sin_addr.s_addr = TCPIP$C_INADDR_ANY; /* * 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 ); } /* * bind ip address and port number to 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 */ 0, /* p1 */ 0, /* p2 */ &addr_itemlst, /* p3 - local socket name */ 0, /* p4 */ 0, /* p5 */ 0 /* p6 */ ); if ( status & STS$M_SUCCESS ) status = iosb.status; if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to bind socket\n" ); exit( status ); } /* * set socket as a listen 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 */ 0, /* p1 */ 0, /* p2 */ 0, /* p3 */ BACKLOG, /* p4 - connection backlog */ 0, /* p5 */ 0 /* p6 */ ); if ( status & STS$M_SUCCESS ) status = iosb.status; if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to set socket passive\n" ); exit( status ); } exit( EXIT_SUCCESS ); } |
Although you can use separate $QIO calls for socket create, bind, and listen operations, you can also perform these operations with one $QIO call. |
A TCP client establishes a connection with a TCP server by issuing the
connect()
function. The
connect()
function initiates a three-way handshake between the client and the
server. This must be successful to establish the connection.
2.5.1 Initiating a Connection (Sockets API)
To initiate a connection to a a TCP server, use the connect() function. Example 2-7 shows a TCP client using the connect() function to initiate a connection to a TCP server.
Example 2-7 Initiating a Connection (Sockets API) |
---|
#include <in.h> /* define internet related constants, */ /* functions, and structures */ #include <inet.h> /* define network address info */ #include <netdb.h> /* define network database library info */ #include <socket.h> /* define BSD socket api */ #include <stdio.h> /* define standard i/o functions */ #include <stdlib.h> /* define standard library functions */ #include <string.h> /* define string handling functions */ #define BUFSZ 1024 /* user input buffer size */ #define PORTNUM 12345 /* server port number */ void get_servaddr( void *addrptr ) { char buf[BUFSIZ]; struct in_addr val; struct hostent *host; while ( TRUE ) { printf( "Enter remote host: " ); if ( fgets(buf, sizeof(buf), stdin) == NULL ) { printf( "Failed to read user input\n" ); exit( EXIT_FAILURE ); } buf[strlen(buf)-1] = 0; val.s_addr = inet_addr( buf ); if ( val.s_addr != INADDR_NONE ) { memcpy( addrptr, &val, sizeof(struct in_addr) ); break; } if ( (host = gethostbyname(buf)) ) { memcpy( addrptr, host->h_addr, sizeof(struct in_addr) ); break; } } } int main( void ) { int sockfd; struct sockaddr_in addr; /* * initialize socket address structure */ memset( &addr, 0, sizeof(addr) ); addr.sin_family = AF_INET; addr.sin_port = htons( PORTNUM ); get_servaddr( &addr.sin_addr ); /* * create a socket */ if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { perror( "Failed to create socket" ); exit( EXIT_FAILURE ); } /* * connect to specified host and port number */ printf( "Initiated connection to host: %s, port: %d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port) ); if ( connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0 ) { perror( "Failed to connect to server" ); exit( EXIT_FAILURE ); } exit( EXIT_SUCCESS ); } |
Previous | Next | Contents | Index |