📄 bsockets.c
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* * (C) 2001 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. */#include "mpidimpl.h"#include "bsocketimpl.h"#ifdef HAVE_STDIO_H#include <stdio.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_SYS_FILIO_H#include <sys/filio.h>#elif defined(HAVE_SYS_IOCTL_H)#include <sys/ioctl.h>#endif#include <stdio.h>#ifdef HAVE_SYS_TIME_H#include <sys/time.h> #endif#include <errno.h> #ifdef HAVE_SYS_PARAM_H#include <sys/param.h>#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif/* FIONBIO (solaris sys/filio.h) */#ifdef HAVE_SYS_IOCTL_H#include <sys/ioctl.h> #endif/* TCP_NODELAY */#ifdef HAVE_NETINET_TCP_H#include <netinet/tcp.h> #endif/* defs of gethostbyname */#ifdef HAVE_NETDB_H#include <netdb.h> #endif#ifdef HAVE_SYS_SELECT_H#include <sys/select.h>#endif#ifdef HAVE_WINSOCK2_H#include <time.h>#endif#ifdef HAVE_NETINET_IN_H#include <netinet/in.h>#endif#ifdef HAVE_ARPA_INET_H#include <arpa/inet.h>#endif/*#define DEBUG_BSOCKET*/#undef DEBUG_BSOCKET#define BPRINTF printf#ifdef DEBUG_BSOCKET#define DBG_MSG(paramlist) BPRINTF( paramlist )#else#define DBG_MSG(paramlist) #endif#if !defined(NO_BSOCKETS)typedef enum { BFD_FD_NOT_IN_USE, BFD_ALLOCATING, BFD_NEW_FD, BFD_BOUND, BFD_LISTENING, BFD_ACCEPTED, BFD_CONNECTED, BFD_WRITING, BFD_READING, BFD_IDLE, BFD_NOT_READY, BFD_SOCKET_READY, BFD_ERROR } BFD_State;struct BFD_Buffer_struct { int real_fd; /* socket descriptor */ int read_flag; /* set if reading */ int write_flag; /* set if writing */ int curpos; /* holds current position in bbuf */ int num_avail; /* bytes in our buffered read buffer */ BFD_State state; /* state of our socket */ int errval; /* errno value */ char read_buf[1]; /* read buffer */ struct BFD_Buffer_struct *next;};BlockAllocator Bsocket_mem;#endif /* !defined(NO_BSOCKETS) */#define BSOCKET_MIN(a, b) ((a) < (b) ? (a) : (b))#define BSOCKET_MAX(a, b) ((a) > (b) ? (a) : (b))static int g_beasy_connection_attempts = 5;#ifdef HAVE_WINSOCK2_Hstatic void log_warning(char *str, ...){ char szMsg[256] = "bsocket error"; HANDLE hEventSource; char *lpszStrings[2]; char pszStr[4096]; va_list list; va_start(list, str); vsprintf(pszStr, str, list); va_end(list); hEventSource = RegisterEventSource(NULL, "bsocket"); lpszStrings[0] = szMsg; lpszStrings[1] = pszStr; if (hEventSource != NULL) { ReportEvent(hEventSource, /* handle of event source */ EVENTLOG_WARNING_TYPE, /* event type */ 0, /* event category */ 0, /* event ID */ NULL, /* current user's SID */ 2, /* strings in lpszStrings */ 0, /* no bytes of raw data */ (LPCTSTR*)lpszStrings,/* array of error strings */ NULL); /* no raw data */ DeregisterEventSource(hEventSource); }}#else#define log_warning()#endif#ifdef NO_BSOCKETSstatic int g_nInitRefCount = 0;int bsocket_init(void){ char *szNum;#ifdef HAVE_WINSOCK2_H WSADATA wsaData; int err;#endif if (g_nInitRefCount) { g_nInitRefCount++; return 0; }#ifdef HAVE_WINSOCK2_H /* Start the Winsock dll */ if ((err = WSAStartup(MAKEWORD(2, 0), &wsaData)) != 0) { err_printf("Winsock2 dll not initialized, error %d\n", err); return err; }#endif szNum = getenv("BSOCKET_CONN_TRIES"); if (szNum != NULL) { g_beasy_connection_attempts = atoi(szNum); if (g_beasy_connection_attempts < 1) g_beasy_connection_attempts = 5; } g_nInitRefCount++; return 0;}int bsocket_finalize(void){ g_nInitRefCount--; if (g_nInitRefCount < 1) g_nInitRefCount = 0; else return 0;#ifdef HAVE_WINSOCK2_H WSACleanup();#endif return 0;}int bwritev(int bfd, B_VECTOR *pIOVec, int n){#ifdef HAVE_WINSOCK2_H DWORD dwNumSent = 0; MPIDI_STATE_DECL(MPID_STATE_BWRITEV); MPIDI_FUNC_ENTER(MPID_STATE_BWRITEV); if (n == 0) { MPIDI_FUNC_EXIT(MPID_STATE_BWRITEV); return 0; } if (WSASend(bfd, pIOVec, n, &dwNumSent, 0, NULL/*overlapped*/, NULL/*completion routine*/) == SOCKET_ERROR) { if (WSAGetLastError() != WSAEWOULDBLOCK) { MPIDI_FUNC_EXIT(MPID_STATE_BWRITEV); return SOCKET_ERROR; } } MPIDI_FUNC_EXIT(MPID_STATE_BWRITEV); return dwNumSent;#else int num_written; MPIDI_STATE_DECL(MPID_STATE_BWRITEV); MPIDI_FUNC_ENTER(MPID_STATE_BWRITEV); num_written = writev(bfd, pIOVec, n); MPIDI_FUNC_EXIT(MPID_STATE_BWRITEV); return num_written;#endif}int breadv(int bfd, B_VECTOR *vec, int veclen){#ifdef HAVE_WINSOCK2_H /*int k;*/ DWORD n = 0; DWORD nFlags = 0;#else int n = 0;#endif MPIDI_STATE_DECL(MPID_STATE_BREADV); MPIDI_FUNC_ENTER(MPID_STATE_BREADV); DBG_MSG("Enter breadv\n"); #ifdef HAVE_WINSOCK2_H if (WSARecv(bfd, vec, veclen, &n, &nFlags, NULL/*overlapped*/, NULL/*completion routine*/) == SOCKET_ERROR) { if (WSAGetLastError() != WSAEWOULDBLOCK) { /* for (k=0; k<veclen; k++) msg_printf("vec[%d] len: %d\nvec[%d] buf: 0x%x\n", k, vec[k].B_VECTOR_LEN, k, vec[k].B_VECTOR_BUF); */ MPIDI_FUNC_EXIT(MPID_STATE_BREADV); return SOCKET_ERROR; } n = 0; }#else n = readv(bfd, vec, veclen);#endif MPIDI_FUNC_EXIT(MPID_STATE_BREADV); return n;}int bmake_nonblocking(int bfd){ int flag = 1; int rc; MPIDI_STATE_DECL(MPID_STATE_BMAKE_NONBLOCKING); MPIDI_FUNC_ENTER(MPID_STATE_BMAKE_NONBLOCKING); DBG_MSG("Enter make_nonblocking\n"); #ifdef HAVE_WINDOWS_SOCKET rc = ioctlsocket(bfd, FIONBIO, &flag);#else rc = ioctl(bfd, FIONBIO, &flag);#endif MPIDI_FUNC_EXIT(MPID_STATE_BMAKE_NONBLOCKING); return rc;}int bmake_blocking(int bfd){ int flag = 0; int rc;\ MPIDI_STATE_DECL(MPID_STATE_BMAKE_BLOCKING); MPIDI_FUNC_ENTER(MPID_STATE_BMAKE_BLOCKING); DBG_MSG("Enter make_blocking\n"); #ifdef HAVE_WINDOWS_SOCKET rc = ioctlsocket(bfd, FIONBIO, &flag);#else rc = ioctl(bfd, FIONBIO, &flag);#endif MPIDI_FUNC_EXIT(MPID_STATE_BMAKE_BLOCKING); return rc;}#else /* #ifdef NO_BSOCKETS */#define BBUF_LOWER_LIMIT 100#define BBUF_DEFAULT_LEN 1024static int g_bbuflen = BBUF_DEFAULT_LEN;/*@ bget_fd - get fd Parameters:+ int bfd - bfd Notes:@*/unsigned int bget_fd(int bfd){ /*dbg_printf("bget_fd\n");*/ return (unsigned int)(((BFD_Buffer*)bfd)->real_fd);}/*@ bcopyset - copy set Parameters:+ bfd_set *dest - destination- bfd_set *src - source Notes:@*/void bcopyset(bfd_set *dest, bfd_set *src){ MPIDI_STATE_DECL(MPID_STATE_BCOPYSET); MPIDI_FUNC_ENTER(MPID_STATE_BCOPYSET); dest->set = src->set; dest->n = src->n; memcpy(dest->p, src->p, src->n * sizeof(void*)); MPIDI_FUNC_EXIT(MPID_STATE_BCOPYSET);}/*@ bset - bset Parameters:+ int bfd - bfd- bfd_set *s - set Notes:@*/void bset(int bfd, bfd_set *s){ int i; MPIDI_STATE_DECL(MPID_STATE_BSET); MPIDI_FUNC_ENTER(MPID_STATE_BSET); /*dbg_printf("bset\n");*/ FD_SET( bget_fd(bfd), & (s) -> set ); for (i=0; i<s->n; i++) { if (s->p[i] == (BFD_Buffer*)bfd) { MPIDI_FUNC_EXIT(MPID_STATE_BSET); return; } } s->p[s->n] = (BFD_Buffer*)bfd; s->n++; MPIDI_FUNC_EXIT(MPID_STATE_BSET);}/*@ bclr - blcr Parameters:+ int bfd - bfd- bfd_set *s - set Notes:@*/void bclr(int bfd, bfd_set *s){ int i; BFD_Buffer* p; MPIDI_STATE_DECL(MPID_STATE_BCLR); MPIDI_FUNC_ENTER(MPID_STATE_BCLR); /*dbg_printf("bclr\n");*/ FD_CLR( bget_fd(bfd), & (s) -> set ); if (s->n == 0) { MPIDI_FUNC_EXIT(MPID_STATE_BCLR); return; } p = (BFD_Buffer*)bfd; for (i=0; i<s->n; i++) { if (s->p[i] == p) { s->p[i] = s->p[s->n-1]; s->n--; MPIDI_FUNC_EXIT(MPID_STATE_BCLR); return; } } MPIDI_FUNC_EXIT(MPID_STATE_BCLR);}/*@bsocket_init - init Notes:@*/static int g_nInitRefCount = 0;int bsocket_init(void){ char *pszEnvVar; char *szNum;#ifdef HAVE_WINSOCK2_H WSADATA wsaData; int err;#endif if (g_nInitRefCount) { g_nInitRefCount++; return 0; }#ifdef HAVE_WINSOCK2_H /* Start the Winsock dll */ if ((err = WSAStartup(MAKEWORD(2, 0), &wsaData)) != 0) { BPRINTF("Winsock2 dll not initialized, error %d\n", err); return err; }#endif szNum = getenv("BSOCKET_CONN_TRIES"); if (szNum != NULL) { g_beasy_connection_attempts = atoi(szNum); if (g_beasy_connection_attempts < 1) g_beasy_connection_attempts = 5; } pszEnvVar = getenv("BSOCKET_BBUFLEN"); if (pszEnvVar != NULL) { g_bbuflen = atoi(pszEnvVar); if (g_bbuflen < BBUF_LOWER_LIMIT) g_bbuflen = BBUF_DEFAULT_LEN; } Bsocket_mem = BlockAllocInit(sizeof(BFD_Buffer) + g_bbuflen, 64, 64, malloc, free); g_nInitRefCount++; return 0;}/*@bsocket_finalize - finalize Notes:@*/int bsocket_finalize(void){ dbg_printf("bsocket_finalize\n"); g_nInitRefCount--; if (g_nInitRefCount < 1) g_nInitRefCount = 0; else return 0; /* Free up the memory used by Bsocket_mem */ BlockAllocFinalize(&Bsocket_mem); #ifdef HAVE_WINSOCK2_H WSACleanup();#endif return 0;}/*@bsocket - socket Parameters:+ int family - family. int type - type- int protocol - protocol Notes:@*/int bsocket(int family, int type, int protocol){#ifdef HAVE_WINSOCK2_H int bfdtemp;#endif BFD_Buffer *pbfd; MPIDI_STATE_DECL(MPID_STATE_BSOCKET); MPIDI_FUNC_ENTER(MPID_STATE_BSOCKET); DBG_MSG("Enter bsocket\n"); /*dbg_printf("bsocket\n");*/ pbfd = (BFD_Buffer *)BlockAlloc( Bsocket_mem ); if (pbfd == 0) { DBG_MSG(("ERROR in bsocket: BlockAlloc returned NULL")); MPIDI_FUNC_EXIT(MPID_STATE_BSOCKET); return BFD_INVALID_SOCKET; } memset(pbfd, 0, sizeof(BFD_Buffer)); pbfd->state = BFD_FD_NOT_IN_USE;#ifdef HAVE_WINSOCK2_H bfdtemp = socket(family, type, protocol); DuplicateHandle(GetCurrentProcess(), (HANDLE)bfdtemp, GetCurrentProcess(), &(HANDLE)(pbfd->real_fd), 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);#else pbfd->real_fd = socket(family, type, protocol);#endif if (pbfd->real_fd == SOCKET_ERROR) { DBG_MSG("ERROR in bsocket: socket returned SOCKET_ERROR\n"); memset(pbfd, 0, sizeof(BFD_Buffer)); BlockFree( Bsocket_mem, pbfd ); MPIDI_FUNC_EXIT(MPID_STATE_BSOCKET); return BFD_INVALID_SOCKET; } MPIDI_FUNC_EXIT(MPID_STATE_BSOCKET); return (int)pbfd;}/*@bbind - bindParameters:+ int bfd - bsocket. const struct sockaddr *servaddr - address- socklen_t servaddr_len - address length Notes:@*/int bbind(int bfd, const struct sockaddr *servaddr, socklen_t servaddr_len){ int ret_val; MPIDI_STATE_DECL(MPID_STATE_BBIND); MPIDI_FUNC_ENTER(MPID_STATE_BBIND); DBG_MSG("Enter bbind\n"); /*dbg_printf("bbind\n");*/ ret_val = bind(((BFD_Buffer*)bfd)->real_fd, servaddr, servaddr_len); MPIDI_FUNC_EXIT(MPID_STATE_BBIND); return ret_val;}/*@blisten - listenParameters:+ int bfd - bsocket- int backlog - backlog Notes:@*/int blisten(int bfd, int backlog){ int ret_val; MPIDI_STATE_DECL(MPID_STATE_BLISTEN); MPIDI_FUNC_ENTER(MPID_STATE_BLISTEN); /*dbg_printf("blisten\n");*/ ret_val = listen(((BFD_Buffer*)bfd)->real_fd, backlog); MPIDI_FUNC_EXIT(MPID_STATE_BLISTEN); return ret_val;}/*@bsetsockopt - setsockopt Parameters: + int bfd - bsocket . int level - level . int optname - optname . const void *optval - optval - socklen_t optlen - optlen Notes:@*/int bsetsockopt(int bfd, int level, int optname, const void *optval, socklen_t optlen){ int ret_val; MPIDI_STATE_DECL(MPID_STATE_BSETSOCKOPT); MPIDI_FUNC_ENTER(MPID_STATE_BSETSOCKOPT); /*dbg_printf("bsetsockopt\n");*/ ret_val = setsockopt(((BFD_Buffer*)bfd)->real_fd, level, optname, optval, optlen); MPIDI_FUNC_EXIT(MPID_STATE_BSETSOCKOPT); return ret_val;}/*@baccept - accept Parameters: + int bfd - bsocket . struct sockaddr *cliaddr - client address - socklen_t *clilen - address length Notes:@*/int baccept(int bfd, struct sockaddr *cliaddr, socklen_t *clilen){ int conn_fd, bfdtemp; BFD_Buffer *new_bfd; MPIDI_STATE_DECL(MPID_STATE_BACCEPT); MPIDI_FUNC_ENTER(MPID_STATE_BACCEPT); DBG_MSG("Enter baccept\n"); /*dbg_printf("baccept\n");*/ bfdtemp = accept(((BFD_Buffer*)bfd)->real_fd, cliaddr, clilen); if (bfdtemp == SOCKET_ERROR) { DBG_MSG("ERROR in baccept: accept returned SOCKET_ERROR\n"); MPIDI_FUNC_EXIT(MPID_STATE_BACCEPT); return BFD_INVALID_SOCKET; } new_bfd = (BFD_Buffer *)BlockAlloc( Bsocket_mem ); if (new_bfd == 0) { DBG_MSG(("ERROR in baccept: BlockAlloc return NULL\n")); MPIDI_FUNC_EXIT(MPID_STATE_BACCEPT); return BFD_INVALID_SOCKET; }#ifdef HAVE_WINSOCK2_H DuplicateHandle(GetCurrentProcess(), (HANDLE)bfdtemp, GetCurrentProcess(), &(HANDLE)conn_fd, 0, FALSE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);#else conn_fd = bfdtemp;#endif memset(new_bfd, 0, sizeof(BFD_Buffer)); new_bfd->real_fd = conn_fd; new_bfd->state = BFD_IDLE; MPIDI_FUNC_EXIT(MPID_STATE_BACCEPT); return (int)new_bfd;}/*@bconnect - connect Parameters: + int bfd - bsocket . const struct sockaddr *servaddr - address - socklen_t servaddr_len - address length Notes:@*/int bconnect(int bfd, const struct sockaddr *servaddr, socklen_t servaddr_len){ int ret_val; MPIDI_STATE_DECL(MPID_STATE_BCONNECT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -