📄 ipcsockets.c
字号:
/*============================================================================= FILE IPCsockets.c Copyright 1991 Georgia Tech Research Corporation, Atlanta, Georgia 30332 All Rights Reserved $Id: ipcsockets.c,v 1.5 2005/06/16 00:28:16 sjborley Exp $ PROJECT ATESSE A-8503 AUTHOR Stefan Roth July 1991 MODIFICATIONS none SUMMARY Generic Interprocess Communication module Provides compatibility for the new SPICE simulator to both the MSPICE user interface and BCP (via ATESSE v.1 style AEGIS mailboxes) and the new ATESSE v.2 Simulator Interface and BCP (via BSD Sockets). This file contains the BSD sockets version. The Simulator is the server, while the SI and BCP will be the clients. INTERFACES FILE ROUTINE CALLED IPC.c ipc_get_line(); REFERENCED FILES Outputs to stderr.=============================================================================*//*============================================================================= DESCRIPTION OF FUNCTIONALITY: Outline of Initialize_Server function: create socket; bind name to socket; getsockname; listen; sock_state = IPC_SOCK_INITIALIZED; return ipc_get_line (); Format of a message line: bytes description ----- ------------------- 0 recognition character for beginning of line; value is BOL_CHAR. 1-4 message length (not including bytes 0-4); 32 bits in htonl format; if value = -1, then EOF and socket should be closed. 5-N+5 message body of length specified in bytes 1-4. The bytes before the message body are the message header. The header length is specified as SOCK_MSG_HDR_LEN bytes. Outline of Get_Line function: read 5 characters; verify that first char is BOL_CHAR; interpret message length (N) from bytes 1-4; do error checking on message header bytes; read N characters as message body; do error checking on message body read; Outline of Send_Line function: write BOL_CHAR; write 4-byte message body length write message body (N bytes) do error checking after each write operation Outline of Terminate_Server function: Continue to read lines (with ipc_transport_get_line) and ignore them until socket EOF is reached; Close the socket.=============================================================================*//* #ifdef IPC_UNIX_SOCKETS */#include "config.h"#ifndef HAS_WINDOWS/*=== INCLUDE FILES ===*/#include "ngspice.h"#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <stdio.h>#include <assert.h>#include <errno.h>#include <fcntl.h>#include <math.h>#include "ipc.h"#include "ipctiein.h"/*=== TYPE DEFINITIONS ===*/ typedef enum { IPC_SOCK_UNINITIALIZED, IPC_SOCK_INITIALIZED, IPC_SOCK_CONNECTED_TO_CLIENT} Ipc_Sock_State_t;/*=== LOCAL VARIABLES ===*/ static int sock_desc; /* socket descriptor */static int msg_stream; /* socket stream */static Ipc_Sock_State_t sock_state = IPC_SOCK_UNINITIALIZED;/*=== INCLUDE FILES ===*/#include "ipcproto.h"/*=============================================================================FUNCTION ipc_transport_initialize_serverAUTHORS July 1991 Stefan RothMODIFICATIONS NONESUMMARY Creates and opens the BSD socket of the server. Listens for requests by a client and then reads the first line message.INTERFACES Called by: (IPC.c) ipc_initialize_server();RETURNED VALUE Ipc_Status_t - returns status of the socket connection.GLOBAL VARIABLES NONENON-STANDARD FEATURES NONE =============================================================================*/Ipc_Status_t ipc_transport_initialize_server (server_name, mode, protocol, batch_filename) char *server_name; /* not used */ Ipc_Mode_t mode; /* not used */ Ipc_Protocol_t protocol; /* IN - only used in assert */ char *batch_filename; /* OUT - returns a value */ /* Note that unused parameters are required to maintain compatibility */ /* with version 1 (mailboxes) functions of the same names. */{ struct sockaddr_in server; /* Server specifications for socket*/ int server_length; /* Size of server structure */ unsigned int port_num; /* Port number converted from server_name */ Ipc_Status_t ipc_get_line (); /* assert (protocol == IPC_PROTOCOL_V2); */ /* allow v1 protocol - wbk */ assert (sock_state == IPC_SOCK_UNINITIALIZED); /* convert server_name (from atesse_xspice invocation line) to a port */ /* number */ port_num = atoi(server_name); if((port_num > 0) && (port_num < 1024)) { /* Reserved port number */ perror ("ERROR: IPC Port numbers below 1024 are reserved"); sock_state = IPC_SOCK_UNINITIALIZED; return IPC_STATUS_ERROR; } sock_desc = socket (AF_INET, SOCK_STREAM, 0); if (sock_desc < 0) { /* Unsuccessful socket opening */ perror ("ERROR: IPC Creating socket"); sock_state = IPC_SOCK_UNINITIALIZED; return IPC_STATUS_ERROR; } /* Socket opened successfully */ server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = port_num; /* SOCKET_PORT; */ server_length = sizeof (server); if (bind (sock_desc, (struct sockaddr *)&server, server_length) < 0) { fprintf (stderr, "ERROR: IPC: Bind unsuccessful\n"); perror ("ERROR: IPC"); sock_state = IPC_SOCK_UNINITIALIZED; return IPC_STATUS_ERROR; } if (getsockname (sock_desc, (struct sockaddr *)&server, &server_length) < 0) { fprintf (stderr, "ERROR: IPC: getting socket name\n"); perror ("ERROR: IPC"); sock_state = IPC_SOCK_UNINITIALIZED; return IPC_STATUS_ERROR; } fprintf (stderr, "Socket port %d.\n", ntohs(server.sin_port)); listen (sock_desc, 5); sock_state = IPC_SOCK_INITIALIZED; /* Socket ok to use now */ /* * First record is the name of the batch filename if we're in batch mode. */ if(g_ipc.mode == IPC_MODE_BATCH) { int len; return ipc_get_line (batch_filename, &len, IPC_WAIT); } /* Return success */ return IPC_STATUS_OK;} /* end ipc_transport_initialize_server *//*=============================================================================FUNCTION bytes_to_integerAUTHORS July 1991 Stefan RothMODIFICATIONS NONESUMMARY Convert four bytes at START in the string STR to a 32-bit unsigned integer. The string is assumed to be in network byte order and the returned value is converted to host byte order (with ntohl).INTERFACES Local to this file. Called by: ipc_transport_get_line();RETURNED VALUE u_long - unsigned 32 bit integerGLOBAL VARIABLES NONENON-STANDARD FEATURES NONE =============================================================================*/static u_long bytes_to_integer (str, start) char *str; /* IN - string that contains the bytes to convert */ int start; /* IN - index into string where bytes are */{ u_long u; /* Value to be returned */ char buff[4]; /* Transfer str into buff to word align reqd data */ int index; /* Index into str and buff for transfer */ /* Get the str+start character and cast it into a u_long and put the value through the network-to-host-short converter and store it in the variable u. */ index = 0; while (index < sizeof(u)) { buff[index] = str[index+start]; index++; } u = ntohl (*((u_long *) buff)); return u;} /* end bytes_to_integer *//*=============================================================================FUNCTION handle_socket_eofAUTHORS July 1991 Stefan RothMODIFICATIONS NONESUMMARY Do processing when the socket reaches EOF or when a message from the client states that EOF has been reached.INTERFACES Local to this file. Called by: ipc_transport_get_line();RETURNED VALUE Ipc_Status_t - always IPC_STATUS_EOFGLOBAL VARIABLES NONENON-STANDARD FEATURES NONE =============================================================================*/static Ipc_Status_t handle_socket_eof (){ close (msg_stream); close (sock_desc); sock_state = IPC_SOCK_UNINITIALIZED; return IPC_STATUS_EOF;} /* handle_socket_eof *//*=============================================================================FUNCTION read_sockAUTHORS July 1991 Stefan RothMODIFICATIONS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -