📄 tcpw32.c
字号:
/******************************************************************* * * * This file is a part of the eXtremeDB HA framework * * Copyright (c) 2001-2006 McObject LLC * * All Rights Reserved * * * *******************************************************************//* * ++ * * PROJECT: eXtremeDB(tm) (c) McObject LLC * * SUBSYSTEM: HA support * * MODULE: tcpw32.C * * ABSTRACT: Low level OS dependent IPC. * Channel-over-TCP, platform dependent functions * * * VERSION: 1.0 * * HISTORY: * 1.0- 1 SS 19-Feb-2004 Created it was * * -- */#ifdef _WIN32#define INCLUDE_SOCKETS#include "interface.h"#ifdef CFG_TCP_SOCKET_CHANNELextern int2 allocate_index();extern void deallocate_index(int2 index);extern uint4 NumBytes;int conn_flag = 0;timer_unit init_time = 0;int commit_initialized = 0;static void init_channel( nw_channel_h chan ){ chan->index = -1; chan->status = 0; chan->socket = -1; chan->event = NULL; chan->event1 = NULL;}/**************************************************************************** * Transport layer. Used by an application for providing of communication * * channels, guaranteed data transfer. Can be used by an application for * * the implementation of it's own communications channels. * * Some details of a communication channel are accessible to application * ****************************************************************************//************************************************************************ * * Description: * * Closes the communication channel * * Parameters: * * IN nw_channel_h ch - pointer to a channel descriptor. * * Return: * * Returns MSO_S_OK if successful or error code (see above). * ************************************************************************/MCO_RET nw_close( nw_channel_h chan){ MCO_RET rc = MCO_S_OK; deallocate_index(chan->index); if(chan->event != NULL) { CloseHandle(chan->event); chan->event = NULL; } if(chan->event1 != NULL) { CloseHandle(chan->event1); chan->event1 = NULL; } if(chan->socket != -1) { if(closesocket(chan->socket)) rc = (MCO_RET)(MCO_E_NW_ERROR); chan->socket = -1; } init_channel(chan); return rc;}/*************************************************************************** * * Description: * * Initializes the network protocol & base channel descriptor. * The base channel is the main channel descriptor used by server for accepting * client's connections requests. The descriptor of base channel MAY contain * extention including common properties of the transport layer. * * Parameters: * * IN nw_channel_h chan - pointer to the base channel descriptor. * * Return: * * Returns MSO_S_OK if successful or error code (see above). * ***************************************************************************/MCO_RET nw_init( nw_channel_h chan){ uint2 wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ return (MCO_RET)(MCO_E_NW_NOTSUPP); } if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup( ); return (MCO_RET)(MCO_E_NW_NOTSUPP); } /* The WinSock DLL is acceptable. Proceed. */ init_channel( chan ); chan->status = NWST_INITIALIZED; // base channel status = initialized return MCO_S_OK;}/************************************************************************** * * Description: * * Creates an overlapped TCP socket. * * IN nw_channel_h ch - pointer to a channel descriptor. * * Returns MSO_S_OK if successful or error code (see above). * **************************************************************************/MCO_RET nw_create_socket( nw_channel_h ch){ int optval = 1; if( (ch->socket= WSASocket(PF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED)) <0) { return (MCO_RET)(MCO_E_NW_FATAL); } setsockopt (ch->socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&optval, sizeof(int) ); setsockopt (ch->socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&optval, sizeof(int) ); return MCO_S_OK;}/************************************************************************ * * Description: * * Sets the listener state of the IO channel. * * Parameters: * * IN nw_channel_h chan - pointer to a channel descriptor. * IN const char * nw_dev - listener channel name * * Return: * * Returns MSO_S_OK if successful or error code (see above). * ************************************************************************/MCO_RET nw_listen( nw_channel_h ch, const char * nw_dev){ uint4 mode = 1; MCO_RET ret; ch->sin.sin_port = htons((int2)atoi(nw_dev)); if( (ret=nw_create_socket(ch)) != MCO_S_OK) { return ret; } ch->sin.sin_family = AF_INET; ch->sin.sin_addr.s_addr = htonl(INADDR_ANY); if ( bind((SOCKET)(ch->socket), (LPSOCKADDR)&ch->sin, sizeof(ch->sin)) != 0 ) { nw_close(ch); return (MCO_RET)(MCO_E_NW_FATAL); } if ( listen((SOCKET)(ch->socket), SOMAXCONN) != 0 ) { nw_close(ch); return (MCO_RET)(MCO_E_NW_BUSY); } if (ioctlsocket(ch->socket, FIONBIO, (PDWORD)&mode) < 0 ) { nw_close(ch); return (MCO_RET)(MCO_E_NW_FATAL); } ch->status |= NWST_LISTEN; return MCO_S_OK;}/************************************************************************ * * Description: * Waits for the connection of a remote host to the IO channel. * * Parameters: * * IN nw_channel_h chan - pointer to the listener channel. * IN OUT nw_channel_h ioch - pointer to the IO channel waiting for connection. * IN timer_unit timeout - wait-for-connect timeout. * * Return: * * Returns MSO_S_OK if successful or error code (see above). * ************************************************************************/MCO_RET nw_accept( nw_channel_h chan, nw_channel_h ioch, timer_unit timeout ){ int csin_len; uint4 mode = 1; TIMEVAL tv, *ptv = NULL; fd_set readfds; int rcs; conn_msg_t msg;#ifdef _SOLARIS int flags;#endif init_channel( ioch ); for(;;) { FD_ZERO(&readfds); FD_SET((SOCKET)chan->socket, &readfds); if(timeout != MCO_TM_INFINITE) { tv.tv_sec = timeout/1000; tv.tv_usec= (timeout%1000)*1000; ptv = &tv; } if( (rcs = select (0, &readfds, 0, 0, ptv) ) == ERROR ) // error { nw_close(chan); return (MCO_RET)(MCO_E_NW_ACCEPT); } if( !rcs ) // timeout { nw_close(chan); return (MCO_RET)(MCO_E_NW_TIMEOUT); } if ( !(FD_ISSET((SOCKET)chan->socket, &readfds) ) ) {ErrRet: nw_close(chan); return (MCO_RET)(MCO_E_NW_ACCEPT); } csin_len = sizeof(ioch->sin); ioch->sin.sin_addr.s_addr = htonl(INADDR_ANY); if ((ioch->socket = (SOCKET)accept(( SOCKET)chan->socket, (LPSOCKADDR)&ioch->sin, &csin_len)) <0 ) { goto ErrRet; }/* copy IP address & port to listener channel in order to give the listener thread opportunity to get them from the listener channel descriptor */ chan->sin.sin_addr.s_addr = ioch->sin.sin_addr.s_addr; chan->sin.sin_port = ioch->sin.sin_port; rcs = 1; setsockopt (ioch->socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&rcs, sizeof(int) ); ioch->event = CreateEvent( NULL, 0, 0, NULL); ioch->event1 = CreateEvent( NULL, 0, 0, NULL); ioch->status |= (NWST_CONNECTED|NWST_INITIALIZED); msg.index = ioch->index=allocate_index(); // channel index if( nw_send ( ioch, (PCHAR)&msg, sizeof(conn_msg_t), timeout) != MCO_S_OK ) { nw_close(ioch); return (MCO_RET)(MCO_E_NW_ACCEPT); } return MCO_S_OK; } }/************************************************************************* * * Description: * Connects IO channel to the remote host by it's name. * * Parameters:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -