JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Programming Interfaces Guide     Oracle Solaris 11 Express 11/10
search filter icon
search icon

Document Information

Preface

1.  Memory and CPU Management

2.  Remote Shared Memory API for Solaris Clusters

3.  Session Description Protocol API

4.  Process Scheduler

5.  Locality Group APIs

6.  Input/Output Interfaces

7.  Interprocess Communication

8.  Socket Interfaces

SunOS 4 Binary Compatibility

Overview of Sockets

Socket Libraries

Socket Types

Interface Sets

Socket Basics

Socket Creation

Binding Local Names

Connection Establishment

Connection Errors

Data Transfer

Closing Sockets

Connecting Stream Sockets

Input/Output Multiplexing

Datagram Sockets

Standard Routines

Host and Service Names

Host Names - hostent

Network Names - netent

Protocol Names - protoent

Service Names - servent

Other Routines

Client-Server Programs

Sockets and Servers

Sockets and Clients

Connectionless Servers

Advanced Socket Topics

Out-of-Band Data

Nonblocking Sockets

Asynchronous Socket I/O

Interrupt-Driven Socket I/O

Signals and Process Group ID

Selecting Specific Protocols

Address Binding

Socket Options

inetd Daemon

Broadcasting and Determining Network Configuration

Using Multicast

Sending IPv4 Multicast Datagrams

Receiving IPv4 Multicast Datagrams

Sending IPv6 Multicast Datagrams

Receiving IPv6 Multicast Datagrams

Stream Control Transmission Protocol

SCTP Stack Implementation

SCTP Socket Interfaces

sctp_bindx()

sctp_opt_info()

sctp_recvmsg()

sctp_sendmsg()

sctp_send()

Branched-off Association

sctp_getpaddrs()

sctp_freepaddrs()

sctp_getladdrs()

sctp_freeladdrs()

Code Examples of SCTP Use

9.  Programming With XTI and TLI

10.  Packet Filtering Hooks

11.  Transport Selection and Name-to-Address Mapping

12.  Real-time Programming and Administration

13.  The Solaris ABI and ABI Tools

A.  UNIX Domain Sockets

Index

Datagram Sockets

A datagram socket provides a symmetric data exchange interface without requiring connection establishment. Each message carries the destination address. The following figure shows the flow of communication between server and client.

The bind(3SOCKET) step for the server is optional.

Figure 8-2 Connectionless Communication Using Datagram Sockets

This graphic depicts data flow between a server and client, using the sendto and recvfrom functions.

Create datagram sockets as described in Socket Creation. If a particular local address is needed, the bind(3SOCKET) operation must precede the first data transmission. Otherwise, the system sets the local address or port when data is first sent. Use sendto(3SOCKET) to send data.

sendto(s, buf, buflen, flags, (struct sockaddr *) &to, tolen);

The s, buf, buflen, and flags parameters are the same as in connection-oriented sockets. The to and tolen values indicate the address of the intended recipient of the message. A locally detected error condition, such as an unreachable network, causes a return of -1 and errno to be set to the error number.

recvfrom(s, buf, buflen, flags, (struct sockaddr *) &from, &fromlen);

To receive messages on a datagram socket, recvfrom(3SOCKET) is used. Before the call, fromlen is set to the size of the from buffer. On return, fromlen is set to the size of the address from which the datagram was received.

Datagram sockets can also use the connect(3SOCKET) call to associate a socket with a specific destination address. The socket can then use the send(3SOCKET) call. Any data that is sent on the socket that does not explicitly specify a destination address is addressed to the connected peer. Only the data that is received from that peer is delivered. A socket can have only one connected address at a time. A second connect(3SOCKET) call changes the destination address. Connect requests on datagram sockets return immediately. The system records the peer's address. Neither accept(3SOCKET) nor listen(3SOCKET) are used with datagram sockets.

A datagram socket can return errors from previous send(3SOCKET) calls asynchronously while the socket is connected. The socket can report these errors on subsequent socket operations. Alternately, the socket can use an option of getsockopt(3SOCKET), SO_ERROR to interrogate the error status.

The following example code shows how to send an Internet call by creating a socket, binding a name to the socket, and sending the message to the socket.

Example 8-5 Sending an Internet Family Datagram

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#define DATA "The sea is calm, the tide is full . . ."   
/*
 * Here I send a datagram to a receiver whose name I get from
 * the command line arguments. The form of the command line is:
 * dgramsend hostname portnumber
 */
main(int argc, char *argv[])
{
    int sock, errnum;
    struct sockaddr_in6 name;
    struct hostent *hp;
    /* Create socket on which to send. */
    sock = socket(AF_INET6,SOCK_DGRAM, 0);
    if (sock == -1) {
        perror("opening datagram socket");
        exit(1);
    }
    /*
     * Construct name, with no wildcards, of the socket to ``send''
     * to. getinodebyname returns a structure including the network
     * address of the specified host. The port number is taken from
     * the command line.
     */
    hp = getipnodebyname(argv[1], AF_INET6, AI_DEFAULT, &errnum);
    if (hp == (struct hostent *) 0) {
        fprintf(stderr, "%s: unknown host\n", argv[1]);
        exit(2);
    }
    bzero (&name, sizeof (name));
    memcpy((char *) &name.sin6_addr, (char *) hp->h_addr,
       hp->h_length);
    name.sin6_family = AF_INET6;
    name.sin6_port = htons(atoi(argv[2]));
    /* Send message. */
    if (sendto(sock,DATA, sizeof DATA ,0,
        (struct sockaddr *) &name,sizeof name) == -1)
        perror("sending datagram message");
    close(sock);
    exit(0);
}

The following sample code shows how to read an Internet call by creating a socket, binding a name to the socket, and then reading from the socket.

Example 8-6 Reading Internet Family Datagrams

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
/*
 * This program creates a datagram socket, binds a name to it, then
 * reads from the socket.
 */
 main()
{
    int sock, length;
    struct sockaddr_in6 name;
    char buf[1024];
    /* Create socket from which to read. */
    sock = socket(AF_INET6, SOCK_DGRAM, 0);
    if (sock == -1) {
        perror("opening datagram socket");
        exit(1);
    }
    /* Create name with wildcards. */
    bzero (&name, sizeof (name));
    name.sin6_family = AF_INET6;
    name.sin6_addr = in6addr_any;
    name.sin6_port = 0;
    if (bind (sock, (struct sockaddr *)&name, sizeof (name)) == -1) {
        perror("binding datagram socket");
        exit(1);
    }
    /* Find assigned port value and print it out. */
    length = sizeof(name);
    if (getsockname(sock,(struct sockaddr *) &name, &length)
            == -1) {
        perror("getting socket name");
        exit(1);
    }
    printf("Socket port #%d\n", ntohs(name.sin6_port));
    /* Read from the socket. */
    if (read(sock, buf, 1024) == -1 )
        perror("receiving datagram packet");
    /* Assumes the data is printable */
    printf("-->%s\n", buf);
    close(sock);
    exit(0);
}