📄 ncbi_socket_connector.c
字号:
/* * =========================================================================== * PRODUCTION $Log: ncbi_socket_connector.c,v $ * PRODUCTION Revision 1000.0 2003/10/29 16:40:19 gouriano * PRODUCTION PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R6.19 * PRODUCTION * =========================================================================== *//* $Id: ncbi_socket_connector.c,v 1000.0 2003/10/29 16:40:19 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Author: Denis Vakatov, Anton Lavrentiev * * File Description: * Implement CONNECTOR for a network socket(based on the NCBI "SOCK"). * * See in "connectr.h" for the detailed specification of the underlying * connector("CONNECTOR", "SConnectorTag") methods and structures. * */#include "ncbi_ansi_ext.h"#include <connect/ncbi_socket_connector.h>#include <stdio.h>#include <stdlib.h>#define MAX_IP_ADDR_LEN 16 /* sizeof("255.255.255.255") *//*********************************************************************** * INTERNAL -- Auxiliary types and static functions ***********************************************************************//* All internal data necessary to perform the (re)connect and i/o */typedef struct { SOCK sock; /* socket; NULL if not connected yet */ char* host; /* server: host */ unsigned short port; /* server: service port */ unsigned int max_try; /* max.number of attempts to establish conn */ void* init_data; /* data to send to the server on connect */ size_t init_size; /* size of the "inst_str" buffer */ TSCC_Flags flags; /* see SOCK_CreateConnectorEx */} SSockConnector;/*********************************************************************** * INTERNAL -- "s_VT_*" functions for the "virt. table" of connector methods ***********************************************************************/#ifdef __cplusplusextern "C" {#endif /* __cplusplus */ static const char* s_VT_GetType (CONNECTOR connector); static char* s_VT_Descr (CONNECTOR connector); static EIO_Status s_VT_Open (CONNECTOR connector, const STimeout* timeout); static EIO_Status s_VT_Wait (CONNECTOR connector, EIO_Event event, const STimeout* timeout); static EIO_Status s_VT_Write (CONNECTOR connector, const void* buf, size_t size, size_t* n_written, const STimeout* timeout); static EIO_Status s_VT_Read (CONNECTOR connector, void* buf, size_t size, size_t* n_read, const STimeout* timeout); static EIO_Status s_VT_Status (CONNECTOR connector, EIO_Event dir); static EIO_Status s_VT_Close (CONNECTOR connector, const STimeout* timeout); static void s_Setup (SMetaConnector* meta, CONNECTOR connector); static void s_Destroy (CONNECTOR connector);# ifdef IMPLEMENTED__CONN_WaitAsync static EIO_Status s_VT_WaitAsync(void* connector, FConnectorAsyncHandler func, SConnectorAsyncHandler* data);# endif#ifdef __cplusplus} /* extern "C" */#endif /* __cplusplus *//*ARGSUSED*/static const char* s_VT_GetType(CONNECTOR connector){ return "SOCK";}static char* s_VT_Descr(CONNECTOR connector){ SSockConnector* xxx = (SSockConnector*) connector->handle; size_t len = strlen(xxx->host) + 6/*:port*/ + 1/*EOL*/; char* buf = (char*) malloc(len); if (buf) sprintf(buf, "%s:%hu", xxx->host, xxx->port); return buf;}static EIO_Status s_VT_Open(CONNECTOR connector, const STimeout* timeout){ SSockConnector* xxx = (SSockConnector*) connector->handle; EIO_Status status = eIO_Unknown; unsigned int i = 0; do { if (xxx->sock && !xxx->host) { /* on-top (connected) connector for the 1st time - only once here*/ unsigned int host; unsigned short port; char addr[MAX_IP_ADDR_LEN]; SOCK_GetPeerAddress(xxx->sock, &host, &port, eNH_HostByteOrder); if (SOCK_ntoa(SOCK_htonl(host), addr, sizeof(addr)) != 0) return eIO_Unknown; xxx->host = strdup(addr); xxx->port = port; status = eIO_Success; } else { if ( !xxx->max_try ) break; /* connect/reconnect */ status = xxx->sock ? SOCK_Reconnect(xxx->sock, 0, 0, timeout) : SOCK_CreateEx(xxx->host, xxx->port, timeout, &xxx->sock, xxx->init_data, xxx->init_size, (xxx->flags & eSCC_DebugPrintout) ? eOn : eDefault); if (xxx->init_data) { free(xxx->init_data); xxx->init_data = 0; xxx->init_size = 0; } i++; } if (status == eIO_Success) { SOCK_SetReadOnWrite(xxx->sock, (xxx->flags & eSCC_SetReadOnWrite) ? eOn : eDefault); break; } /* error: continue trying */ } while (i < xxx->max_try); return status;}static EIO_Status s_VT_Status(CONNECTOR connector, EIO_Event dir){ SSockConnector* xxx = (SSockConnector*) connector->handle; return xxx->sock ? SOCK_Status(xxx->sock, dir) : eIO_Success;}static EIO_Status s_VT_Wait(CONNECTOR connector, EIO_Event event, const STimeout* timeout){ SSockConnector* xxx = (SSockConnector*) connector->handle; assert(event == eIO_Read || event == eIO_Write); return xxx->sock ? SOCK_Wait(xxx->sock, event, timeout) : eIO_Closed;}static EIO_Status s_VT_Write(CONNECTOR connector, const void* buf, size_t size, size_t* n_written, const STimeout* timeout){ SSockConnector* xxx = (SSockConnector*) connector->handle; if (!xxx->sock) return eIO_Closed; SOCK_SetTimeout(xxx->sock, eIO_Write, timeout); return SOCK_Write(xxx->sock, buf, size, n_written, eIO_WritePlain);}static EIO_Status s_VT_Read(CONNECTOR connector, void* buf, size_t size, size_t* n_read, const STimeout* timeout){ SSockConnector* xxx = (SSockConnector*) connector->handle; if (!xxx->sock) return eIO_Closed; SOCK_SetTimeout(xxx->sock, eIO_Read, timeout); return SOCK_Read(xxx->sock, buf, size, n_read, eIO_ReadPlain);}static EIO_Status s_VT_Close(CONNECTOR connector, const STimeout* timeout){ SSockConnector* xxx = (SSockConnector*) connector->handle; EIO_Status status = eIO_Success; if (xxx->sock) { SOCK_SetTimeout(xxx->sock, eIO_Write, timeout); status = SOCK_Close(xxx->sock); xxx->sock = 0; } return status;}#ifdef IMPLEMENTED__CONN_WaitAsyncstatic EIO_Status s_VT_WaitAsync(void* connector, FConnectorAsyncHandler func, SConnectorAsyncHandler* data){ return eIO_NotSupported;}#endifstatic void s_Setup(SMetaConnector* meta, CONNECTOR connector){ /* initialize virtual table */ CONN_SET_METHOD(meta, get_type, s_VT_GetType, connector); CONN_SET_METHOD(meta, descr, s_VT_Descr, connector); CONN_SET_METHOD(meta, open, s_VT_Open, connector); CONN_SET_METHOD(meta, wait, s_VT_Wait, connector); CONN_SET_METHOD(meta, write, s_VT_Write, connector); CONN_SET_METHOD(meta, flush, 0, 0); CONN_SET_METHOD(meta, read, s_VT_Read, connector); CONN_SET_METHOD(meta, status, s_VT_Status, connector); CONN_SET_METHOD(meta, close, s_VT_Close, connector);#ifdef IMPLEMENTED__CONN_WaitAsync CONN_SET_METHOD(meta, wait_async, s_VT_WaitAsync, connector);#endif meta->default_timeout = 0; /*infinite*/}static void s_Destroy(CONNECTOR connector){ SSockConnector* xxx = (SSockConnector*) connector->handle; if (xxx->host) free(xxx->host); if (xxx->init_data) free(xxx->init_data); free(xxx); connector->handle = 0; free(connector);}static CONNECTOR s_Init(SOCK sock, const char* host, unsigned short port, unsigned int max_try, const void* init_data, size_t init_size, TSCC_Flags flags){ CONNECTOR ccc = (SConnector *) malloc(sizeof(SConnector )); SSockConnector* xxx = (SSockConnector*) malloc(sizeof(SSockConnector)); /* parameter check: either sock or host/port, not both */ assert((!sock && host && port) || (sock && !host && !port)); assert(!init_size || init_data); /* initialize internal data structures */ xxx->sock = sock; xxx->host = host ? strdup(host) : 0; xxx->port = port; if (sock) xxx->max_try = SOCK_IsServerSide(sock) ? 0 : max_try; else xxx->max_try = max_try ? max_try : 1; xxx->flags = flags; xxx->init_size = init_data ? init_size : 0; if (xxx->init_size) { xxx->init_data = malloc(init_size); memcpy(xxx->init_data, init_data, xxx->init_size); } else { xxx->init_data = 0; } /* initialize connector data */ ccc->handle = xxx; ccc->next = 0; ccc->meta = 0; ccc->setup = s_Setup; ccc->destroy = s_Destroy; return ccc;}/*********************************************************************** * EXTERNAL -- the connector's "constructors" ***********************************************************************/extern CONNECTOR SOCK_CreateConnector(const char* host, unsigned short port, unsigned int max_try){ return s_Init(0, host, port, max_try, 0, 0, 0);}extern CONNECTOR SOCK_CreateConnectorEx(const char* host, unsigned short port, unsigned int max_try, const void* init_data, size_t init_size, TSCC_Flags flags){ return s_Init(0, host, port, max_try, init_data, init_size, flags);}extern CONNECTOR SOCK_CreateConnectorOnTop(SOCK sock, unsigned int max_try){ return s_Init(sock, 0, 0, max_try, 0, 0, 0);}extern CONNECTOR SOCK_CreateConnectorOnTopEx(SOCK sock, unsigned int max_try, TSCC_Flags flags){ return s_Init(sock, 0, 0, max_try, 0, 0, flags);}/* * -------------------------------------------------------------------------- * $Log: ncbi_socket_connector.c,v $ * Revision 1000.0 2003/10/29 16:40:19 gouriano * PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R6.19 * * Revision 6.19 2003/08/25 14:42:14 lavr * Employ new k..Timeout constants -- log modification only * * Revision 6.18 2003/05/31 05:15:45 lavr * Add ARGSUSED where args are meant to be unused, remove Flush * * Revision 6.17 2003/05/27 15:04:31 lavr * +#include <stdio.h> (to define sprint's prototype on Mac) * * Revision 6.16 2003/05/14 03:54:23 lavr * SOCKET_CreateConnectorOnTopEx(): number of parameters changed * Implementation of CONN_Description() added * * Revision 6.15 2003/01/17 19:44:47 lavr * Reduce dependencies * * Revision 6.14 2002/12/04 16:55:45 lavr * Take advantage of SOCK_CreateEx() * * Revision 6.13 2002/10/28 15:46:21 lavr * Use "ncbi_ansi_ext.h" privately * * Revision 6.12 2002/10/22 15:11:24 lavr * Zero connector's handle to crash if revisited * * Revision 6.11 2002/08/12 15:12:46 lavr * Use persistent SOCK_Write() * * Revision 6.10 2002/08/12 15:06:58 lavr * Use persistent SOCK_Write() * * Revision 6.9 2002/08/07 16:37:45 lavr * EIO_ReadMethod enums changed accordingly; * eSCC_SetReadOnWrite processing added * * Revision 6.8 2002/04/26 16:37:05 lavr * Added setting of default timeout in meta-connector's setup routine * Remove all checks for kDefaultTimeout: now supplied good from CONN * * Revision 6.7 2001/12/04 15:55:07 lavr * +SOCK_CreateConnectorOnTop(), +SOCK_CreateConnectorOnTopEx() * Redesign of open-retry loop * * Revision 6.6 2001/04/24 21:30:27 lavr * Added treatment of kDefaultTimeout * * Revision 6.5 2001/01/25 17:04:44 lavr * Reversed:: DESTROY method calls free() to delete connector structure * * Revision 6.4 2001/01/23 23:09:47 lavr * Flags added to 'Ex' constructor * * Revision 6.3 2001/01/11 16:38:18 lavr * free(connector) removed from s_Destroy function * (now always called from outside, in METACONN_Remove) * * Revision 6.2 2000/12/29 18:16:26 lavr * Adapted for use of new connector structure. * * Revision 6.1 2000/04/07 20:05:38 vakatov * Initial revision * * ========================================================================== */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -