Migration Guide NetIPC to BSD Sockets and DSCOPY to FTP FINAL TRIM SIZE : 7.5 in x 9.
FINAL TRIM SIZE : 7.5 in x 9.
Legal Notice Hewlett-Packard makes no warranty of any kind with regard to this material, including, but not limited to, the implied warranties of merchantability and tness for a particular purpose. Hewlett-Packard shall not be liable for errors contained herein or for incidental or consequential damages in connection with the furnishing, performance, or use of this material.
Printing History New editions are complete revisions of the manual. Updates, which are issued between editions, contain additional and replacement pages to be merged into the manual. The dates on the title page change only when a new edition or a new update is published. Note that many product updates and xes do not require manual changes and, conversely, manual corrections may be done without accompanying product changes.
In This Guide This guide provides information about how to migrate NetIPC client/server applications to Berkeley Software Distribution (BSD) Sockets and about how to migrate from DSCOPY/9000 to FTP/9000. This guide also describes how to port UNIX BSD Socket applications to the HP 3000 MPE/iX platform. Although both AF UNIX and AF INET are address families used with BSD Sockets, this guide only discusses the AF INET address family.
FINAL TRIM SIZE : 7.5 in x 9.
Contents 1. Introduction Before You Begin . . . . . . . . . . Additional References . . . . . . . HP 9000 Manuals . . . . . . . . HP 3000 Manuals . . . . . . . . HP 1000 Manuals . . . . . . . . PC Manuals . . . . . . . . . . NetIPC to BSD Sockets Call Mapping The Socket Registry . . . . . . . . 2. NetIPC to BSD IPC Migration Migration Overview . . . . . . . . . Con guration Considerations . . . . . Name to IP Address Resolution . . . Port Name to Port Address Resolution IP to LAN Address Resolution . .
HP 3000 Include File Call Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-21 2-22 2-23 2-24 2-26 2-27 2-27 2-28 2-28 2-28 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-3 3-4 3-5 3-6 BSD Sockets Overview . . . . . . . . . . . . Establishing Connections . . . . . . . . . . Transferring Data . .
HP 3000 Include File 5. DSCOPY/9000 to FTP/9000 Migration DSCOPY Options and FTP Commands . . . . . . . . A. NetIPC Sample Programs NetIPC Client Program . . . . . . . . . . . . . . . NetIPC Server Program . . . . . . . . . . . . . . . B. BSD IPC Sample Programs BSD IPC Client Program . . . . . . . . . . . . . . . BSD IPC Server Program . . . . . . . . . . . . . . C. NetIPC Sample Include File HP 3000 Include File . . . . . . . . . . . . . . . .
Figures 3-1. 3-2. 4-1. 4-2. BSD Sockets to NetIPC Communication . . . NetIPC to BSD Sockets Communication . . . BSD Socket to Socket Communication . . . . Porting BSD Applications to HP 3000 Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . NetIPC to BSD Sockets Call Mapping . . . . . . BSD Sockets Implementations - Calls . . . . . BSD Sockets Implementations - Routines . . . . DSCOPY Options and Equivalent FTP Commands . . . . . . . . . . . . . . . . . . . . . 1-5 . 4-13 .
1 Introduction FINAL TRIM SIZE : 7.5 in x 9.
Introduction To prevent unnecessary maintenance of di erent versions of applications for di erent vendor's platforms, Hewlett-Packard provides the components, tools, and solutions for application developers to move from proprietary to open client/server solutions.
Introduction Reduced support costs. BSD applications use standard protocols. This makes troubleshooting easier. Additionally, the BSD Sockets API is an industry standard with reference books and courses available from a variety of di erent sources. The intent of this guide is to make the transition to standards based client/server APIs easier for application developers. In some cases, your applications may have to communicate with NetIPC applications running on MPE-based or RTE-based systems.
Before You Begin Before you begin the process of migrating your applications, you may need to review the following sections: Additional references. NetIPC to BSD Sockets call mapping. The Socket Registry.
Introduction Before You Begin NetIPC to BSD Sockets Call Mapping NetIPC and BSD Sockets are simply interfaces to the TCP/IP transport protocol; they are not end-to-end protocols in themselves. As a result, BSD applications can communicate with NetIPC applications. While a one-to-one mapping of NetIPC and BSD calls is not possible, both NetIPC and BSD Sockets provide similar functionality. The following table shows the relationship between NetIPC and BSD Sockets calls.
Introduction Before You Begin The Socket Registry A NetIPC feature that has no direct BSD Sockets equivalent is the facility for named sockets, called the Socket Registry. The Socket Registry enables users to dynamically name sockets and register them, so other users can nd the socket by name. The system calls to access and modify this registry are IPCLOOKUP() and IPCNAME().
2 NetIPC to BSD IPC Migration FINAL TRIM SIZE : 7.5 in x 9.
NetIPC to BSD IPC Migration Migration Overview The following is a brief overview that outlines the process of migrating NetIPC client/server applications to BSD Sockets. Install and con gure ARPA Services on your HP 9000 system or your PC. For information on installing ARPA Services/9000 refer to Installing and Administering ARPA Services. For information on installing PC ARPA Services, refer to the PC Sockets Programmer's Guide. Add the server's hostname to the /etc/hosts le (HOSTS.NET.
Con guration Considerations To allow client/server applications to run on di erent platforms, you must consistently con gure both the client and server systems. The following sections describe the required con guration for converting a NetIPC client/server application to BSD Sockets. Name to IP Address Resolution Client applications typically identify systems using a hostname.
NetIPC to BSD IPC Migration Con guration Considerations system (HOSTS.NET.SYS for MPE/iX) or by using the nslookup command on an HP 9000 system to determine if a name server is used. Port Name to Port Address Resolution Client applications identify a service residing on a remote host using a service name. The service name must be converted to a port address before the request is sent to the host. With NetIPC, the server application registers a server name by calling ipcname().
NetIPC to BSD IPC Migration Con guration Considerations IP to LAN Address Resolution NetIPC uses the proprietary Probe protocol to resolve IP addresses and may optionally use the industry standard ARP protocol. Begining with MPE/iX Release 4.0, the proprietary Probe protocol can be turned o , allowing only the ARP protocol to be used to resolve IP addresses. BSD Sockets use the industry standard ARP protocol.
Overall Socket Di erences Sockets are a generic term used in NetIPC and BSD IPC to describe an endpoint for network communications. In NetIPC, there is a distinct di erence between the connecting call sockets (referenced by source and destination descriptors) and the Virtual Circuit (VC) sockets (referenced by connection descriptors). In BSD IPC, all the sockets involved are simply BSD sockets.
Include Files NetIPC and BSD Sockets use di erent include les. The following lists the include les used for each type of application. NetIPC Include Files NetIPC applications use the following include les: HP 9000 #include HP 3000 #include HP 1000 See Appendix C for an example. None PC #include BSD IPC Include Files BSD IPC applications use the following include les: HP 9000 #include #include #include
NetIPC to BSD IPC Migration Include Files HP 3000 #include #include #include #include #include #include #include #include #include HP 1000 #include #include #include #include #include #include #include #include #include #include #include #include
Setting Up Connections When calling ipcdest() or ipclookup(), you must use the NS nodename for the location parameter on an HP 9000 system. An HP 3000 MPE/iX system allows you to use an Internet hostname. NetIPC uses the Probe protocol or the HP 3000 Network Directory to resolve hostname to IP address. Probe proxy can also be used to accomplish address resolution. On an HP 3000 running MPE/iX 4.0 or later, you can disable the Probe protocol.
NetIPC to BSD IPC Migration Setting Up Connections The opt parameter of the ipccreate() call \maps" to the address parameter of the BSD bind() call. To ensure the interoperability between di erent platforms, you should use addresses in the range of 30767 through 32767 (decimal). The location parameter (nodename) of the ipcdest() call \maps" to the name parameter of the BSD gethostbyname() call.
NetIPC to BSD IPC Migration Setting Up Connections ipclookup() On a NetIPC client, the ipclookup() call is used to look up the socket name in the server's Socket Registry (see chapter 1). It is similar to the combination of the BSD gethostbyname() and getservbyname() calls. The getservbyname() call returns a structure containing the port address of the service. The following examples assume that the service name and the well-known port are con gured together in the /etc/services le (SERVICES.NET.
NetIPC to BSD IPC Migration Setting Up Connections ipccreate() On a NetIPC server, the ipccreate() call is used to create a source socket descriptor. It is similar to the BSD socket() and bind() calls. socket() creates a BSD socket and returns the socket descriptor for the socket. On a server the socket is usually bound to a well-known address through the bind() call. The server then listens at the address. The bind() call is optional on the client side.
NetIPC to BSD IPC Migration Setting Up Connections ipcdest() On a NetIPC client, the ipcdest() call is used to create a destination descriptor on a call to ipcconnect(). This destination descriptor contains the information necessary to connect to a remote socket (IP address and port address). For BSD Sockets, the sockaddr_in structure contains similar information that you must explicitly ll in.
NetIPC to BSD IPC Migration Setting Up Connections The port could also be hardcoded or obtained by getservbyname(). Here is an example. peeraddr.sin_port = sp -> s_port; OR peeraddr.sin_port = TCP_WELL_KNOWN_PORT; optoverhead() The NetIPC optoverhead() call returns the number of bytes required in the option record. This feature is not required in applications that use BSD Sockets and should be removed. initopt() The NetIPC initopt() call initializes the option record.
Establishing Connections To start a connection, the NetIPC server must create a call socket. The socket can be created for a well-known address (port) or registered with a name in the Socket Registry. A client looks up the socket name and uses the protocol and destination address information to establish a connection. With BSD IPC, when a socket is created on a server, it is bound to a well-known port. Clients establish connection by sending connection requests to the port.
NetIPC to BSD IPC Migration Establishing Connections Call Mapping The following explains how NetIPC and BSD Sockets calls \map" for establishing connections. Here is an overview of the di erences. The source socket descriptor parameter of the ipcconnect() call \maps" to the socket descriptor parameter of the BSD connect() call. The destination socket descriptor parameter of the ipcconnect() call \maps" to the server address parameter of the BSD connect() call.
NetIPC to BSD IPC Migration Establishing Connections ipcconnect() On the client, the ipcconnect() call is used to establish a virtual circuit between the source descriptor and the socket described by the destination descriptor. It is equivalent to the BSD connect() call.
NetIPC to BSD IPC Migration Establishing Connections ipcrecvcn() On the server, the ipcrecvcn() call is used to wait for connection requests from clients after a call socket has been created. The corresponding BSD IPC call is accept(). accept() may be called after a listen() has been performed on the socket.
NetIPC to BSD IPC Migration Establishing Connections ipccontrol() The ipccontrol() call is used to modify connection characteristics. It is similar to the BSD ioctl() and setsockopt() calls.
Transferring Data For HP 3000 applications, the NetIPC ipcrecv() and ipcsend() calls correspond to the BSD recv() and send() calls (respectively). With the MPE/iX 4.5 release, this functionality is also performed by the BSD read() and write() calls. For HP 9000, HP 1000, and PC applications, NetIPC has the ability to wait for a speci ed amount of data to receive, while the BSD recv() call will return as long as more than 1 byte of data transferred on a socket. BSD IPC supports partial data transfer.
NetIPC to BSD IPC Migration Transferring Data Call Mapping The following explains how NetIPC and BSD Sockets calls \map" for transferring data. Here is an overview of the di erences. The code examples assume that you are using blocked mode. By default ipcrecv() blocks for 60 seconds while recv() blocks inde nitely. However, recv() users can have timeouts by enabling signals and using the alarm() function.
NetIPC to BSD IPC Migration Transferring Data ipcrecv() The ipcrecv() call is used to receive a response to a connection request and to receive user data on a connection. Its equivalents in BSD are recv(), recvfrom(), and recvmsg(). Only recv() will be presented in the code examples.
NetIPC to BSD IPC Migration Transferring Data ipcsend() The ipcsend() call is used to transmit data on a connection. Its equivalents in BSD are send(), sendto(), and sendmsg(). Only send() will be presented in the code examples.
NetIPC to BSD IPC Migration Transferring Data ipcselect() On the server, the ipcselect() (select() for MPE/iX and also HP 9000) call is used to provide a synchronous multiplexing mechanism. The ipcselect() call returns when at least one socket is ready for reading or writing or the socket has received a connection request. It is equivalent to the BSD select() call. NetIPC Example /* The following shows an implementation of selecting from a maximum of 60 sockets.
NetIPC to BSD IPC Migration Transferring Data BSD Example /* The following code segment uses the pre-defined structs and macros to manipulate bitmap masks.
Terminating Connections When you call ipcshutdown(), all the data remaining in the socket queue may be lost without notice. To ensure that no data is lost during connection shutdown, you must specify the NSF GRACEFUL RELEASE ag. BSD IPC supports the shutdown() system call on HP 9000, HP 3000, and HP 1000 systems. However, BSD IPC shutdown() is not equivalent to NetIPC ipcshutdown(). This shutdown() call provides a means to stop either sending or receiving data or both. It does not shut down a connection.
NetIPC to BSD IPC Migration Terminating Connections Call Mapping The following explains how NetIPC and BSD Sockets calls \map" for terminating connections. ipcshutdown() The ipcshutdown() call is similar to the BSD IPC close() call. For PC BSD sockets, use the close socket() call.
Byte Order Conversion Routines HP RISC-based and Motorola 680X0-based computers process bytes in standard TCP/IP byte order, known as network byte order. PCs, however, use Intel architecture and process bytes in reverse order, known as host byte order. PC programmers, therefore, must be aware of this di erence, especially when lling in socket address structures. The PC socket developer's kits provide library routines for converting between the two architectures.
3 NetIPC and BSD IPC Communication FINAL TRIM SIZE : 7.5 in x 9.
NetIPC and BSD IPC Communication Figure 3-1 illustrates how a BSD Sockets application communicates with a NetIPC application. Figure 3-1. BSD Sockets to NetIPC Communication 3-2 FINAL TRIM SIZE : 7.5 in x 9.
BSD IPC Client and NetIPC Server The NetIPC server must create a well-known port rather than relying on ipcname() which uses the Socket Registry. The BSD client will not be able to nd the NetIPC server if the server relies on ipcname(), since BSD Sockets cannot access the Socket Registry. The NetIPC server creates its socket at a well-known port during the ipccreate() call.
NetIPC and BSD IPC Communication BSD IPC Client and NetIPC Server Creating a Well-Known Port On a NetIPC server, ipccreate() with an appropriate option containing the well-known port, is used. The option record is created using the initopt() and addopt() calls. The NetIPC initopt() call initializes the option record, and the NetIPC addopt() call adds the well-known port to the option record. The following example does not include any error checking.
NetIPC Client and BSD IPC Server Similar to the BSD client to NetIPC server communications, a NetIPC client process can connect to a BSD server. Figure 3-2 shows the communications between the NetIPC client and the BSD Sockets application server. Figure 3-2. NetIPC to BSD Sockets Communication The NetIPC client cannot use ipclookup() to nd the server node and service by name. Since BSD Sockets do not support the Socket Registry, the client must use ipcdest() with a well-known socket.
NetIPC and BSD IPC Communication NetIPC Client and BSD IPC Server may not have called accept() by the time the ipcrecv() returns even though ipcconnect() returns without an error. You can try to send and receive data after the initial ipcrecv() call, but ipcsend() and ipcrecv() may block before the BSD IPC application has called accept() to actually accept the connection.
4 BSD IPC Porting FINAL TRIM SIZE : 7.5 in x 9.
BSD IPC Porting The 4.3 version of Berkeley Software Distribution (BSD) o ers a rich set of interprocess-communication (IPC) facilities referred to as Berkeley Sockets or BSD sockets. This chapter provides an overview of BSD Sockets and information about porting applications to the HP 3000 MPE/iX environment. In addition, this chapter discusses how to modify existing applications. 4-2 FINAL TRIM SIZE : 7.5 in x 9.
BSD Sockets Overview Berkeley Sockets provide a C language application program interface (API) that is used as a de facto standard in writing many of the current distributed applications. This API provides a general interface to allow node-isolated and network-based applications to be constructed independently of the underlying communication facilities. With the 4.0 release of MPE/iX, HP introduced the rst portion of Berkeley Sockets/iX.
BSD IPC Porting BSD Sockets Overview Figure 4-1. BSD Socket to Socket Communication Establishing Connections To establish a connection, the client process calls socket() to create the local data structure (see gure 4-1, step 1c). socket() creates an endpoint for communication and returns a descriptor which is used in all subsequent socket-related calls: s=socket (AF_INET, SOCK_STREAM, 0); The server calls socket() to create the local data structure.
BSD IPC Porting BSD Sockets Overview listen queue is established for the socket speci ed by the s parameter (see gure 4-1, step 1s): listen(ls,5). The client requests a connection to the server's socket by calling connect() and blocking until the server has accepted the request (see gure 4-1, step 2c): connect (s, &peeraddr_in, sizeof(struct sockaddr_in)) The server calls accept(), and completes the \connection establishment phase" (see gure 4-1, step 2s).
BSD IPC Porting BSD Sockets Overview Utility Calls The gethostent, gethostbyname, and gethostbyaddr subroutines return a pointer to an object with the elds that re ect information obtained from either the /etc/hosts (HOSTS.NET.SYS for MPE/iX) database or one of the name services identi ed in the /etc/services (SERVICES.NET.SYS for MPE/iX) le.
Porting BSD Applications to HP 3000 MPE/iX Environment The following steps describe the process of porting BSD IPC applications from HP 9000 to HP 3000 systems. Refer to the owchart in gure 4-2 for an illustration of this process. Identify unsupported BSD calls in the HP 9000 application. Modify the HP 9000 application to run on the HP 3000. Ensure that all the necessary include les are in the same group/account. Test the client/server applications. Figure 4-2.
BSD IPC Porting Porting BSD Applications to HP 3000 MPE/iX Environment MPE/iX 4.0 Supported Calls The 4.0 release of the MPE/iX operating system introduced the rst portion of Berkeley Sockets system calls. All of these calls and intrinsics are used in the MPE/iX environment exactly as in the UNIX environment, for example, the same parameters apply.
Modifying Current Applications Here is more speci c information to help you modify your existing applications. Establishing Connections for Datagram Sockets Since connect() and recv() are not supported for datagram sockets, you should remove the connect() calls and replace the recv() calls with recvfrom() calls. If the source address is not the desired address when data is received, then the message is discarded and a new recvfrom() is posted.
BSD IPC Porting Modifying Current Applications you are using sendmsg() and recvmsg() to exchange le descriptors, there is no recommended modi cation. Here is an example of how to convert a vectored data call. Assume that MSG points to the message structure used for sendmsg(). Within the structure is a pointer to an array of vectors, and each vector consists of a pointer and length. The message structure also contains a count of the number of vectors in the send().
BSD IPC Porting Modifying Current Applications Considerations for Di erent Compilers You may nd that your HP 9000 application includes UNIX calls that need to be translated to MPE/iX Operating System calls. Refer to the UNIX to MPE/iX Cross Reference Guide. This cross-reference guide is meant to assist software developers in porting their applications from UNIX platforms to MPE/iX platforms.
BSD Sockets Compilation Procedure To compile a BSD IPC application, you need to create a library list le, called rllist, by entering following line: libc.net.sys, socketrl.net.sys. After creating the le, use the following steps to compile an application. 1. ccxl file_name obj_file; info="-D_SOURCE-SOCKET" 2. link from=objc_file; to=exec_file; cap=ia,ba,ph; rl=^rllist; The following tables summarize the BSD Sockets implementations for di erent platforms. 4-12 FINAL TRIM SIZE : 7.5 in x 9.
BSD IPC Porting BSD Sockets Compilation Procedure Table 4-1. BSD Sockets Implementations - Calls Type of Call Establish Connection Calls: HP-UX BSD 4.
BSD IPC Porting BSD Sockets Compilation Procedure Table 4-2. BSD Sockets Implementations - Routines Type of Routine Byte Order Conversion Routines: Internet Address Routines: Domain Name Routines: HP-UX BSD 4.3 ntohs() ntohl() htons() htonl() BSD Sockets/iX ntohs() ntohl() htons() htonl() inet_addr() inet_network() inet_ntoa() inet_makeaddr() inet_netof() inet_inaof() res_init() res_send() res_mkquery() res_query() res_search() dn_expand() dn_comp() 4-14 FINAL TRIM SIZE : 7.5 in x 9.
BSD IPC Porting BSD Sockets Compilation Procedure Table 4-2. BSD Sockets Implementations - Routines (continued) Type of Routine HP-UX BSD 4.
BSD IPC Porting BSD Sockets Compilation Procedure FINAL TRIM SIZE : 7.5 in x 9.
5 DSCOPY/9000 to FTP/9000 Migration FINAL TRIM SIZE : 7.5 in x 9.
DSCOPY/9000 to FTP/9000 Migration In the ongoing e ort to promote standards for open systems networking, Hewlett-Packard recommends migrating from DSCOPY on the HP 9000 to FTP on the HP 9000. FTP/9000 is part of the well-known ARPA services and is already the predominant standard for le transfers between HP 3000, HP 9000, and HP 1000 systems. For more information on using FTP on the HP 9000, refer to Using ARPA Services.
DSCOPY Options and FTP Commands Following is a table that summarizes all of the DSCOPY options used on the HP 3000 S9xx and HP 9000 and the equivalent FTP commands that you can use to achieve the same result. FTP on the HP 9000 provides most of the functionality that DSCOPY does. FTP 3000/9000/1000 refers to the ARPA FTP service on the HP 3000 S9xx, HP 9000, and HP 1000. Note the di erences between transfers to an HP 3000 S9xx or HP 1000 and transfers to an HP 9000.
DSCOPY/9000 to FTP/9000 Migration DSCOPY Options and FTP Commands Table 5-1.
A NetIPC Sample Programs FINAL TRIM SIZE : 7.5 in x 9.
NetIPC Sample Programs This appendix includes two working NetIPC sample programs, a client program and a server program. Use these programs as templates for your own applications. A-2 FINAL TRIM SIZE : 7.5 in x 9.
NetIPC Client Program /*--------------------------------------------------------------------------*/ /* */ /* Client: NetIPC Client Sample Program (non-Windows) */ /* */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* COPYRIGHT (C) 1988 HEWLETT-PACKARD COMPANY. */ /* All rights reserved.
NetIPC Sample Programs NetIPC Client Program #define LINT_ARGS #include #include #include #include #include
NetIPC Sample Programs NetIPC Client Program /************************** FORWARD DECLARATIONS ***************************/ void void void void void ErrorRoutine(char * , int , ns_int_t ); ReceiveData(ns_int_t , char * ); SetUp(char * , ns_int_t * ); ShutdownDescriptor(ns_int_t ); CleanUp(); /*************************** GLOBAL VARIABLES ******************************/ static char version[] = "@(#) PC NetIPC client program. Version B.00.
NetIPC Sample Programs NetIPC Client Program /* ** Create call socket and connect to the server */ SetUp(node_name, &cd); /* ** Process any incoming requests until "EOT" is received.
NetIPC Sample Programs NetIPC Client Program printf("Client data is: %s\n", data_buf); } else { printf("Received EOT\n"); break; } } /* while ( strcmp(requested_name, "EOT") != 0); */ CleanUp(); return 0; } /* main */ /***************************************************************************/ /* */ /* Routine: SetUp */ /* */ /* Description: Perform setup operations: Create a TCP call socket, */ /* create destination descriptor for Server's well-known */ /* call socket, establish VC with Server, set the
NetIPC Sample Programs NetIPC Client Program /* ** A call socket is created by calling IPCCREATE. The value returned ** in the sd parameter will be used in the subsequent calls. */ ipccreate(NS_CALL, NSP_TCP, NULL, NULL, &sd, &result); if (result != NSR_NO_ERROR) ErrorRoutine("SetUp calling ipcCreate", result, sd); /* ** The server is waiting on a well-known address (TCP_ADDRESS). ** Create the destination descriptor for the socket from the ** remote node.
NetIPC Sample Programs NetIPC Client Program ipcrecv(*cd, &request, &dlen, &flags, NULL, &result); if (result != NSR_NO_ERROR) ErrorRoutine("Setup calling ipcRecv", result, *cd); /* ** Shutdown the source and destination descriptors since we don't ** need them any more. */ } ShutdownDescriptor(sd); ShutdownDescriptor(dd); /***************************************************************************/ /* */ /* Routine: ReceiveData */ /* */ /* Description: Receives data from Server.
NetIPC Sample Programs NetIPC Client Program initopt(opt, 0, &res16); if (res16 != NSR_NO_ERROR) ErrorRoutine("ReceiveData calling initopt",res16, cd); flags = 0; amount_to_recv = INFOBUFLEN; buffer = info_buf; amt_recvd = 0; while (amt_recvd < amount_to_recv ) { rc = amount_to_recv; /* This is a two way value, input=max to recv, ** output = amount received.
NetIPC Sample Programs NetIPC Client Program void CleanUp() { ShutdownDescriptor(cd); exit(1); } /***************************************************************************/ /* */ /* Routine: ErrorRoutine */ /* */ /* Description: We have some error, so print a message and then call */ /* CleanUp which will shutdown all descriptors and terminate */ /* the program. */ /* */ /* Input: Msg - string which contains the name of the routine who */ /* had the error.
NetIPC Sample Programs NetIPC Client Program } if (errno) perror("\n"); CleanUp(); /***************************************************************************/ /* */ /* Routine: ShutdownDescriptor */ /* */ /* Description: Shutdowns a given descriptor. This descriptor can be */ /* either a source or connection descriptor. */ /* */ /* Input: desc - descriptor to be shutdown.
NetIPC Server Program /*---------------------------------------------------------------------------*/ /* */ /* SERVER: NetIPC Server Sample Program */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* COPYRIGHT (C) 1988 HEWLETT-PACKARD COMPANY. */ /* All rights reserved.
NetIPC Sample Programs NetIPC Server Program * Since all IPC calls (except IPCCREATE) are done nowait, the main loop * calls IPCWait, determines what type of event completed, and calls the * appropriate procedure to handle the event. *--------------------------------------------------------------------------*/ #define LINT_ARGS #include
NetIPC Sample Programs NetIPC Server Program #define #define #define #define TCP_ADDRESS 31500 RECOVERABLE 1 IRRECOVERABLE 2 NSR_GRACEFUL_RELEASE 68 /* This is not defined in
NetIPC Sample Programs NetIPC Server Program /************ PROTOTYPE DECLARATIONS FOR COMPILER PARAMETER CHECKING********/ void ErrorRoutine(char * , int , ns_int_t , int ); int HandleNewRequest(ns_int_t ); void ProcessRead(ns_int_t , unsigned ); void ReadData(char * , char *); void SetUp(); void InitiateConnection(ns_int_t * ); void ShutdownDescriptor(ns_int_t * ); void CheckFile(); void CleanUp(); void RejectRequest(ns_int_t ); int FindVcInTable(ns_int_t , ns_int_t ** ); char *sock_strerror(int); /*****
NetIPC Sample Programs NetIPC Server Program FD_ZERO((fd_set *) &readfds); FD_ZERO((fd_set *) &exceptfds); /* ** Create a call socket with a well known address for the clients ** to use. */ SetUp(); /* ** ** ** ** */ The num_recvcns_posted variable keeps track of the number of outstanding connection requested. We only want one at a time. If we get up to the maximum number of VCs established, then we will have zero recvcns posted.
NetIPC Sample Programs NetIPC Server Program /* ** ** ** ** ** ** ** ** ** */ Check the listen queue for any new connection requests. Decrement the recvcns_posted count, and handle the new request. HandleNewRequest returns TRUE if it successfully created another session. If so, increment the count. New NetIPC connections are indicated as an exception on hp-ux, but as a read event on MPEiX. If BSD Sockets where used, hp-ux would also handle a connection request as a read event.
NetIPC Sample Programs NetIPC Server Program /***************************************************************************/ /* */ /* Routine: CheckFile */ /* */ /* Description: Check that the file can be opened.
NetIPC Sample Programs NetIPC Server Program void SetUp() { short int int short int short int int option[100], res16; result; timeout; port_address; i; /* ** Set up the opt array for the parm we will use.
NetIPC Sample Programs NetIPC Server Program /* ** Set the 'select' bits. */ FD_SET(sd, &readfds); FD_SET(sd, &exceptfds); /* ** Inititalize the vc_table */ } for (i=0; i < MAX_NUM_VCS; i++) vc_table[i].cd = INACTIVE_DESCRIPTOR; /***************************************************************************/ /* */ /* Routine: CleanUp */ /* */ /* Description: We have some problem, so we need to shutdown all of */ /* the descriptors and terminate the program.
NetIPC Sample Programs NetIPC Server Program } for (i = 0; i < MAX_NUM_VCS; i++) { if (vc_table[i].cd != INACTIVE_DESCRIPTOR) ShutdownDescriptor(&vc_table[i].cd); } exit(1); /***************************************************************************/ /* */ /* Routine: ErrorRoutine */ /* */ /* Description: */ /* We have some error, so print a message. If the severity is */ /* IRRECOVERABLE, call CleanUp which will shutdown all descriptors */ /* and terminate the program.
NetIPC Sample Programs NetIPC Server Program ipcerrmsg(error, buffer, &buffer_size, &result); if (result) printf("ipcerrmg failed!\n"); else printf("Server: NetIPC error %s\n",buffer); } if (severity == IRRECOVERABLE) CleanUp(); #undef BUFFSIZE /***************************************************************************/ /* */ /* Routine: FindVcInTable */ /* */ /* Description: Searches the VC table for a given descriptor */ /* */ /* Input: cd - descriptor to search the VC table for */ /* */ /* Output:
NetIPC Sample Programs NetIPC Server Program } if (i < MAX_NUM_VCS) { return(TRUE); } else { return(FALSE); } /***************************************************************************/ /* */ /* Routine: HandleNewRequest */ /* */ /* Description: A new client wants to talk to us, complete the vc */ /* establishment. */ /* */ /* Input: cd - descriptor for the newly completed virtual circuit. */ /* */ /* Output: NONE */ /* */ /* Returns: TRUE if another recvcn was posted, else FALSE.
NetIPC Sample Programs NetIPC Server Program for (i=0; i < MAX_NUM_VCS; i++) { if (vc_table[i].cd == INACTIVE_DESCRIPTOR) break; } /* ** ** ** ** */ } If we found an available vc descriptor in the vc_table, then initiate another connection. If we are out of available descriptors, then skip it; We will then initiate a connection as an existing connection is shutdown. if (i < MAX_NUM_VCS) { InitiateConnection(&vc_table[i].cd); return(TRUE); } else /* This should never happen...
NetIPC Sample Programs NetIPC Server Program { int ns_int_t char int ns_flags_t result; dlen; *buffer; i; flags; /* ** We have received data on the given VC. ** So determine which VC from the vc_table we have. */ for (i = 0; i < MAX_NUM_VCS; i++) { if (cd == vc_table[i].cd) break; } if (i == MAX_NUM_VCS) ErrorRoutine("ProcessRead", 0, cd, IRRECOVERABLE); /* ** Receive the data */ for (vc_table[i].amount_received= 0 ; vc_table[i].amount_received < INBUFFERLEN; vc_table[i].
NetIPC Sample Programs NetIPC Server Program #ifdef _MPEIX if ((result == NSR_REMOTE_ABORT) || (result == NSR_GRACEFUL_RELEASE)) { ShutdownDescriptor(&vc_table[i].cd); return; } else #endif ErrorRoutine("ProcessRead calling ipcrecv", result, cd, IRRECOVERABLE); } /* ** ** ** ** */ If we have all of the name from the client, then get the data we need from the file to send to the client. But first, NULL terminate the name field. So we can print it out in ReadData. vc_table[i].
NetIPC Sample Programs NetIPC Server Program /***************************************************************************/ /* */ /* Routine: ReadData */ /* */ /* Description: From the file 'datafile' look for the given name and */ /* if found return the information on the given name. If the */ /* given name is not found return a string that says so. */ /* */ /* Input: name - a string name keyword to search for in 'datafile' */ /* */ /* Output: output_buffer - contains the information found for name.
NetIPC Sample Programs NetIPC Server Program while (fgets(input_buffer, sizeof(input_buffer), datafile) != NULL) { /* ** Now see if the name matches the name key. Compare at most ** INBUFFERLEN characters and ignore cases during the compare. */ if (strncmp(name, input_buffer, INBUFFERLEN) == 0) { /* ** ** ** */ We found the name the client requested in the file. So fill the input line with spaces starting where the newline character which gets() puts on at the end of the line.
NetIPC Sample Programs NetIPC Server Program } /* ** If we did not find the name, continue searching the file. */ /* search the file */ /* ** ** ** */ We've fallen out of the while loop because we reached the end of the file. Print an error message and put a 60-byte error message in the data buffer. printf("Server: %s not in file.\n", name); strncpy(output_buffer, "SERVER did not find the requested name in the datafile. OUTBUFLEN); ", /* ** Close the datafile and return.
NetIPC Sample Programs NetIPC Server Program void InitiateConnection(cd) ns_int_t *cd; { int result; /* ** Initiate the connection. NOTE: on a PC, the ipcrecvCn is always ** an unblocked call. So we do not need to enable NOWAIT I/O here.
NetIPC Sample Programs NetIPC Server Program void ShutdownDescriptor(desc) ns_int_t *desc; { int result; ipcshutdown(*desc, NULL, NULL, &result); /* ** Don't worry about errors here, since there isn't much we can do.
B BSD IPC Sample Programs FINAL TRIM SIZE : 7.5 in x 9.
BSD IPC Sample Programs This appendix includes two working BSD IPC sample programs, a client program and a server program. Use these programs as templates for your own applications. B-2 FINAL TRIM SIZE : 7.5 in x 9.
BSD IPC Client Program /*--------------------------------------------------------------------------*/ /* */ /* Client: BSD Sockets Client Sample Program (non-Windows) */ /* */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* COPYRIGHT (C) 1988 HEWLETT-PACKARD COMPANY. */ /* All rights reserved.
BSD IPC Sample Programs BSD IPC Client Program #include #include #include #include /* BSD Sockets Include Files */ #include #include #include #include /* needed for 3k and 9k systems */ #define #define #define BUFFERLEN INFOBUFLEN TCP_ADDRESS ** ** ** ** ** */ 20 60 31500 /* Well-known server address. For BSD ** SOCKETS, you could add a service to the /etc/services file (services.net.
BSD IPC Sample Programs BSD IPC Client Program /**************************************************************************/ /* */ /* Procedure: main */ /* */ /* Purpose: Prompts the user for a remote node name. Sets up a */ /* connection to the server. Then continually prompts the */ /* user for names to send to the server to lookup. Then */ /* receives the information buffer associated with the */ /* name from the server.
BSD IPC Sample Programs BSD IPC Client Program if (strcmp(requested_name, "EOT") != 0) { /* ** Pad the name with spaces so that send is always BUFFERLEN ** in length. */ for (i = strlen(requested_name); i < requested_name[i] = ' '; /* ** */ BUFFERLEN; i++) Send the request to the server. num = send(sd, requested_name, BUFFERLEN, 0); if (num < 0) { errptr = sock_strerror(errno); printf("send(): %s (%d)\n", errptr, errno); CleanUp(); } /* ** */ Get information buffer from server.
BSD IPC Sample Programs BSD IPC Client Program /**************************************************************************/ /* */ /* Routine: SetUp */ /* */ /* Description: Perform setup operations: Create a socket and */ /* connect to the server's well-known port. */ /* */ /* Input: host_name - name of remote host running server program. */ /* */ /* Output: sd - socket descriptor.
BSD IPC Sample Programs BSD IPC Client Program hp = gethostbyname((char *) host_name); if (hp == NULL) { printf("Unable to locate host entry.\n"); CleanUp(); } #ifdef GETSERVBYNAME /* ** The well-known port number is determined by calling ** getservbyname(). */ sp = getservbyname(serv_name, "tcp"); if (sp == NULL) { printf("Unable to locate service entry.\n"); CleanUp(); } #endif /* ** A socket is created by calling socket(). The value returned ** willl be used in subsequent calls.
BSD IPC Sample Programs BSD IPC Client Program rc = connect(sd, &server, sizeof(struct sockaddr_in)); if (rc < 0) { errptr = sock_strerror(errno); printf("connect(): %s (%d)\n", errptr, errno); CleanUp(); } /* Set sd for non-blocking i/o mode */ #ifdef _NONBLOCK rc = ioctl(sd, FIOSNBIO, &flag); if (rc < 0) { errptr = sock_strerror(errno); printf("ioctl(): %s (%d)\n", errptr, errno); CleanUp(); } #endif } /**************************************************************************/ /* */ /* Routine: Receive
BSD IPC Sample Programs BSD IPC Client Program while (amt_recvd < amt_to_recv){ rc = recv(sd, buff, amt_to_recv, 0); if ( rc < 0 ) { if (errno != EWOULDBLOCK){ /* This is for Non-Blocked i/o */ error = errno; errptr = sock_strerror(errno); printf("ReceiveData recv: %s (%d)\n",errptr, error); } rc = 0; } amt_recvd += rc; } /* ** */ } Tack on an extra NULL so we can print the info out using printf().
BSD IPC Server Program /*---------------------------------------------------------------------------*/ /* */ /* SERVER: BSD Sockets Server Sample Program */ /* */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* COPYRIGHT (C) 1988 HEWLETT-PACKARD COMPANY. */ /* All rights reserved.
BSD IPC Sample Programs BSD IPC Server Program #include #include #include #include #include #include /* BSD Sockets Include Files */ #include #include #include #include #define #define #define #define #define #define #define
BSD IPC Sample Programs BSD IPC Server Program /* ** The nfds variable is used by select.
BSD IPC Sample Programs BSD IPC Server Program /* ** */ Check that the data file can be opened. CheckFile(); /* ** */ Initialize the client socket descriptor table. for (i = 0; i < MAX_NUM_SOCKETS; i++) { csd_table[i].sd = INACTIVE_DESCRIPTOR; } /* ** */ Initialize the descriptor sets. FD_ZERO((fd_set *) &readfds); /* ** ** */ Create a call socket with a well known address for the clients to use. SetUp(); /* ** ** ** ** ** ** ** ** ** ** */ Loop forever waiting to serve clients.
BSD IPC Sample Programs BSD IPC Server Program nfds = sd + 1; while (TRUE) { rfds = readfds; nfound = select(nfds, (int *)&rfds, 0, 0, 0); printf("nfds: %d\n", nfds); if (nfound < 0) { errptr = sock_strerror(errno); fprintf(stderr, "select(): %s (%d)\n", errptr, errno); CleanUp(); } /* ** ** ** ** */ Check the listen queue for any new connection requests. Decrement the recvcns_posted count, and handle the new request. HandleNewRequest returns TRUE if it successfully created another session.
BSD IPC Sample Programs BSD IPC Server Program /***************************************************************************/ /* */ /* Routine: CheckFile */ /* */ /* Description: Check that the file can be opened. */ /* */ /* Input: NONE */ /* */ /* Output: NONE */ /* */ /* Global variables referenced: */ /* */ /***************************************************************************/ void CheckFile() { FILE *fd; } if ((fd = fopen("datafile", "r")) == NULL) { fprintf(stderr, "Unable to open datafile.
BSD IPC Sample Programs BSD IPC Server Program void SetUp() { char option[40]; int result; int timeout; int port_address; char *errptr; int rc; struct hostent *hp; #ifdef GETSERVBYNAME struct servent *sp; #endif struct sockaddr_in sa; char localhost[MAXHOSTNAME]; /* allocate and clear out address structure for 3k and 9k */ memset ((char*)&sa, 0, sizeof(struct sockaddr_in)); #ifdef GETSERVBYNAME /* ** Lookup the well-known port to use.
BSD IPC Sample Programs BSD IPC Server Program /* ** */ Create a socket. sd = socket(AF_INET, SOCK_STREAM, 0); if (sd < 0) { errptr = sock_strerror(errno); fprintf(stderr, "socket(): %s (%d)\n", errptr, errno); CleanUp(); } /* ** */ Bind the socket to the well-known port.
BSD IPC Sample Programs BSD IPC Server Program /***************************************************************************/ /* */ /* Routine: HandleNewRequest */ /* */ /* Description: A new client wants to talk, establish the vc. */ /* */ /* Input: cd - descriptor for the newly completed virtual circuit. */ /* */ /* Output: NONE */ /* */ /* Returns: TRUE if another recvcn was posted, else FALSE.
BSD IPC Sample Programs BSD IPC Server Program /***************************************************************************/ /* */ /* Routine: InitiateConnection */ /* */ /* Description: Initiates a connection by calling accept */ /* */ /* Input: NONE */ /* */ /* Output: cd - connection descriptor for the new connection.
BSD IPC Sample Programs BSD IPC Server Program /* ** ** */ The nfds global variable should be set to one more than the highest numbered descriptor used. nfds++; vcs_available--; } /***************************************************************************/ /* */ /* Routine: ProcessRead */ /* */ /* Description: We have a client program which has send in a read */ /* request. So process the read. */ /* */ /* Input: cd - descriptor for the virtual circuit.
BSD IPC Sample Programs BSD IPC Server Program amt_recvd = 0; while (amt_recvd < amt_to_recv){ rc = recv(csd, inbuff, amt_to_recv, 0); if ( (rc == 0) || ( (rc < 0) & ( errno = ECONNRESET )) ) { /* Received a fin (bsd client) or a reset (NetIPC client) */ ShutdownDescriptor(csd); return; } if ( rc < 0 ) { if (errno != EWOULDBLOCK){ /* This is for Non-Blocked i/o */ error = errno; errptr = sock_strerror(errno); printf("ReceiveData recv: %s (%d)\n",errptr, error); } rc = 0; } amt_recvd += rc; } /* ** ** ** *
BSD IPC Sample Programs BSD IPC Server Program /***************************************************************************/ /* */ /* Routine: ReadData */ /* */ /* Description: From the file 'datafile' look for the given name and */ /* if found return the information on the given name. If the */ /* given name is not found return a string that says so. */ /* */ /* Input: name - a string name keyword to search for in 'datafile' */ /* */ /* Output: output_buffer - contains the information found for name.
BSD IPC Sample Programs BSD IPC Server Program /* ** Now see if the name matches the name key. Compare at most ** INBUFFLEN characters and ignore cases during the compare. */ if (strncmp(name, input_buffer, INBUFFLEN) == 0) { /* ** ** */ We found the name the client requested in the file. So fill the input line with spaces starting where the newline character which gets() puts on at the end of the line.
BSD IPC Sample Programs BSD IPC Server Program /* ** ** ** */ We've fallen out of the while loop because we reached the end of the file. Print an error message and put a 60-byte error message in the data buffer. printf("Server: %s not in file.\n", name); strncpy(output_buffer, "SERVER did not find the requested name in the datafile. OUTBUFFLEN); /* ** */ } ", Close the datafile and return.
BSD IPC Sample Programs BSD IPC Server Program if (csd == csd_table[i].sd) { csd_table[i].sd = INACTIVE_DESCRIPTOR; rc = TRUE; break; } } if (rc != TRUE) { fprintf(stderr, "Unable to find socket descriptor in table.\n"); } /* ** ** ** */ } Remove client socket descriptor from the descriptor sets, close down the descriptor, and decrement the number of open descriptors.
BSD IPC Sample Programs BSD IPC Server Program void CleanUp() { int i; /* ** */ Shutdown the source descriptor. ShutdownDescriptor(sd); /* ** ** */ Shutdown all of the VC's that are active in the csd_table. Once again don't worry about errors. for (i = 0; i < MAX_NUM_SOCKETS; i++) { if (csd_table[i].sd != INACTIVE_DESCRIPTOR) { ShutdownDescriptor(csd_table[i].sd); } } /* ** */ } Exit with a non-zero result.
BSD IPC Sample Programs BSD IPC Server Program FINAL TRIM SIZE : 7.5 in x 9.
C NetIPC Sample Include File FINAL TRIM SIZE : 7.5 in x 9.
NetIPC Sample Include File This appendix includes a sample NetIPC include le. Use this sample le as a template for your own applications. C-2 FINAL TRIM SIZE : 7.5 in x 9.
HP 3000 Include File /* $Header: ns_ipc.h,v 1.51.61.3 92/04/22 12:05:33 smp Exp $ */ #ifndef _SYS_NS_IPC_INCLUDED #define _SYS_NS_IPC_INCLUDED /* ns_ipc.h: NetIPC (NS) definitions */ #ifdef _KERNEL_BUILD #include "../h/stdsyms.h" #else /* ! _KERNEL_BUILD */ #include "stdsyms" #endif /* _KERNEL_BUILD */ #ifdef _INCLUDE_HPUX_SOURCE /* Types */ #ifdef _KERNEL_BUILD # include "../h/types.h" #else /* ! _KERNEL_BUILD */ # include
NetIPC Sample Include File HP 3000 Include File # ifndef _MPEIX # ifdef _PROTOTYPES extern void addopt(short [], short, short, short, short [], short *); extern void initopt(short [], short, short *); extern int optoverhead(short, short *); extern void readopt(short [], short, short *, short *, short [], short *); extern char *ipcerrstr(int); extern void ipcerrmsg(int, char *, int *, int *); extern void ipcconnect(ns_int_t, ns_int_t, ns_int_t *, short [], ns_int_t *, ns_int_t *); extern void ipccontrol(ns
NetIPC Sample Include File HP 3000 Include File # # # # else /* not _PROTOTYPES */ extern void addopt(); extern void initopt(); extern int optoverhead(); extern void readopt(); extern char *ipcerrstr(); extern void ipcerrmsg(); extern void ipcconnect(); extern void ipccontrol(); extern void ipccreate(); extern void ipcdest(); extern void ipcgetnodename(); extern void ipclookup(); extern void ipcname(); extern void ipcnameerase(); extern void ipcrecv(); extern void ipcrecvcn(); extern void ipcselect(); e
NetIPC Sample Include File HP 3000 Include File # /* * protocol IDs */ define NSP_TCP # # # # # # /* * flags values */ define NSF_VECTORED define NSF_PREVIEW define NSF_MORE_DATA define NSF_DATA_WAIT define NSF_GRACEFUL_RELEASE define NSF_MESSAGE_MODE # # # # # # # # # # /* * ipccontrol() request values */ define NSC_NBIO_ENABLE define NSC_NBIO_DISABLE define NSC_TIMEOUT_RESET define NSC_TIMEOUT_GET define NSC_SOCKADDR define NSC_RECV_THRESH_RESET define NSC_SEND_THRESH_RESET define NSC_RECV_THRESH_G
NetIPC Sample Include File HP 3000 Include File # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # /* * Netipc errors */ define NSR_NO_ERROR 000 define NSR_BOUNDS_VIO 3 define NSR_NETWORK_DOWN 4 define NSR_SOCK_KIND 5 define NSR_PROTOCOL 6 define NSR_FLAGS 7 define NSR_OPT_OPTION 8 define NSR_PROTOCOL_NOT_ACTIVE 9 define NSR_KIND_AND_PROTOCOL 10 define NSR_NO_MEMORY 11 define NSR_ADDR_OPT 14 define NSR_NO_FILE_AVAIL 15 define NSR_OPT_SYNTAX 18 define NSR_DUP_OPTION
NetIPC Sample Include File HP 3000 Include File # # # # # # # # # # # # # # define define define define define define define define define define define define define define # /* used to map kernel errors to NSR equivalents */ define NIPC_ERROR_OFFSET 10000 # # # # # # # /* these exist for historical reasons */ define NSO_MIN_BURST_IN 7 define NSO_MIN_BURST_OUT 11 define NSOL_MIN_BURST_IN 2 define NSOL_MIN_BURST_OUT 2 define NSOL_MAX_CONN_REQ_BACK 2 define NSOL_MAX_RECV_SIZE 2 define NSOL_MAX_SEND_SI