⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sockgen.c

📁 一个典型的用于嵌入式Linux环境的Webserver
💻 C
📖 第 1 页 / 共 2 页
字号:
}#endif /* ! UEMF *//******************************************************************************//* *	Define the events of interest */void socketRegisterInterest(socket_t *sp, int handlerMask){	a_assert(sp);	sp->handlerMask = handlerMask;#ifndef UEMF	if (handlerMask) {		sp->fileHandle = emfCreateFileHandler(sp->sock, handlerMask,			(emfFileProc *) socketEventProc, (void *) sp->sid);	} else {		emfDeleteFileHandler(sp->fileHandle);		sp->fileHandle = -1;	}#endif /* ! UEMF */}/******************************************************************************//* *	Wait until an event occurs on a socket. Return 1 on success, 0 on failure. *	or -1 on exception (UEMF only) */int socketWaitForEvent(socket_t *sp, int handlerMask, int *errCode){	int	mask;	a_assert(sp);	mask = sp->handlerMask;	sp->handlerMask |= handlerMask;	while (socketSelect(sp->sid, 1000)) {		if (sp->currentEvents & (handlerMask | SOCKET_EXCEPTION)) {			break;		}	}	sp->handlerMask = mask;	if (sp->currentEvents & SOCKET_EXCEPTION) {		return -1;	} else if (sp->currentEvents & handlerMask) {		return 1;	}	if (errCode) {		*errCode = errno = EWOULDBLOCK;	}	return 0;}/******************************************************************************//* *	Return TRUE if there is a socket with an event ready to process, */int socketReady(int sid){	socket_t 	*sp;	int			all;	all = 0;	if (sid < 0) {		sid = 0;		all = 1;	}	for (; sid < socketMax; sid++) {		if ((sp = socketList[sid]) == NULL) {			if (! all) {				break;			} else {				continue;			}		} 		if (sp->flags & SOCKET_CONNRESET) {			socketCloseConnection(sid);			return 0;		}		if (sp->currentEvents & sp->handlerMask) {			return 1;		}/* *		If there is input data, also call select to test for new events */		if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid) > 0) {			socketSelect(sid, 0);			return 1;		}		if (! all) {			break;		}	}	return 0;}/******************************************************************************//* * 	Wait for a handle to become readable or writable and return a number of  *	noticed events. Timeout is in milliseconds. */#if (defined (WIN) || defined (CE) || defined (NW))int socketSelect(int sid, int timeout){	struct timeval	tv;	socket_t		*sp;	fd_set		 	readFds, writeFds, exceptFds;	int 			nEvents;	int				all, socketHighestFd;	/* Highest socket fd opened */	FD_ZERO(&readFds);	FD_ZERO(&writeFds);	FD_ZERO(&exceptFds);	socketHighestFd = -1;	tv.tv_sec = timeout / 1000;	tv.tv_usec = (timeout % 1000) * 1000;/* *	Set the select event masks for events to watch */	all = nEvents = 0;	if (sid < 0) {		all++;		sid = 0;	}	for (; sid < socketMax; sid++) {		if ((sp = socketList[sid]) == NULL) {			continue;		}		a_assert(sp);/* * 		Set the appropriate bit in the ready masks for the sp->sock. */		if (sp->handlerMask & SOCKET_READABLE) {			FD_SET(sp->sock, &readFds);			nEvents++;			if (socketInputBuffered(sid) > 0) {				tv.tv_sec = 0;				tv.tv_usec = 0;			}		}		if (sp->handlerMask & SOCKET_WRITABLE) {			FD_SET(sp->sock, &writeFds);			nEvents++;		}		if (sp->handlerMask & SOCKET_EXCEPTION) {			FD_SET(sp->sock, &exceptFds);			nEvents++;		}		if (! all) {			break;		}	}/* *	Windows select() fails if no descriptors are set, instead of just sleeping *	like other, nice select() calls. So, if WIN, sleep. */	if (nEvents == 0) {		Sleep(timeout);		return 0;	}/* * 	Wait for the event or a timeout. */	nEvents = select(socketHighestFd+1, &readFds, &writeFds, &exceptFds, &tv);	if (all) {		sid = 0;	}	for (; sid < socketMax; sid++) {		if ((sp = socketList[sid]) == NULL) {			continue;		}		if (FD_ISSET(sp->sock, &readFds) || socketInputBuffered(sid) > 0) {				sp->currentEvents |= SOCKET_READABLE;		}		if (FD_ISSET(sp->sock, &writeFds)) {				sp->currentEvents |= SOCKET_WRITABLE;		}		if (FD_ISSET(sp->sock, &exceptFds)) {				sp->currentEvents |= SOCKET_EXCEPTION;		}		if (! all) {			break;		}	}	return nEvents;}#else /* not WIN || CE || NW */int socketSelect(int sid, int timeout){	socket_t		*sp;	struct timeval	tv;	fd_mask 		*readFds, *writeFds, *exceptFds;	int 			all, len, nwords, index, bit, nEvents;/* *	Allocate and zero the select masks */	nwords = (socketHighestFd + NFDBITS) / NFDBITS;	len = nwords * sizeof(int);	readFds = balloc(B_L, len);	memset(readFds, 0, len);	writeFds = balloc(B_L, len);	memset(writeFds, 0, len);	exceptFds = balloc(B_L, len);	memset(exceptFds, 0, len);	tv.tv_sec = timeout / 1000;	tv.tv_usec = (timeout % 1000) * 1000;/* *	Set the select event masks for events to watch */	all = nEvents = 0;	if (sid < 0) {		all++;		sid = 0;	}	for (; sid < socketMax; sid++) {		if ((sp = socketList[sid]) == NULL) {			if (all == 0) {				break;			} else {				continue;			}		}		a_assert(sp);/* * 		Initialize the ready masks and compute the mask offsets. */		index = sp->sock / (NBBY * sizeof(fd_mask));		bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask)));		/* * 		Set the appropriate bit in the ready masks for the sp->sock. */		if (sp->handlerMask & SOCKET_READABLE) {			readFds[index] |= bit;			nEvents++;			if (socketInputBuffered(sid) > 0) {				tv.tv_sec = 0;				tv.tv_usec = 0;			}		}		if (sp->handlerMask & SOCKET_WRITABLE) {			writeFds[index] |= bit;			nEvents++;		}		if (sp->handlerMask & SOCKET_EXCEPTION) {			exceptFds[index] |= bit;			nEvents++;		}		if (! all) {			break;		}	}/* * 	Wait for the event or a timeout. Reset nEvents to be the number of actual *	events now. */	nEvents = select(socketHighestFd + 1, (fd_set *) readFds,		(fd_set *) writeFds, (fd_set *) exceptFds, &tv);	if (nEvents > 0) {		if (all) {			sid = 0;		}		for (; sid < socketMax; sid++) {			if ((sp = socketList[sid]) == NULL) {				if (all == 0) {					break;				} else {					continue;				}			}			index = sp->sock / (NBBY * sizeof(fd_mask));			bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask)));			if (readFds[index] & bit || socketInputBuffered(sid) > 0) {				sp->currentEvents |= SOCKET_READABLE;			}			if (writeFds[index] & bit) {				sp->currentEvents |= SOCKET_WRITABLE;			}			if (exceptFds[index] & bit) {				sp->currentEvents |= SOCKET_EXCEPTION;			}			if (! all) {				break;			}		}	}	bfree(B_L, readFds);	bfree(B_L, writeFds);	bfree(B_L, exceptFds);	return nEvents;}#endif /* WIN || CE *//******************************************************************************//* *	Process socket events */void socketProcess(int sid){	socket_t	*sp;	int			all;	all = 0;	if (sid < 0) {		all = 1;		sid = 0;	}/* * 	Process each socket */	for (; sid < socketMax; sid++) {		if ((sp = socketList[sid]) == NULL) {			if (! all) {				break;			} else {				continue;			}		}		if (socketReady(sid)) {			socketDoEvent(sp);		}		if (! all) {			break;		}	}}/******************************************************************************//* *	Process an event on the event queue */static int socketDoEvent(socket_t *sp){	ringq_t		*rq;	int 		sid;	a_assert(sp);	sid = sp->sid;	if (sp->currentEvents & SOCKET_READABLE) {		if (sp->flags & SOCKET_LISTENING) { 			socketAccept(sp);			sp->currentEvents = 0;			return 1;		} 	} else {/* *		If there is still read data in the buffers, trigger the read handler *		NOTE: this may busy spin if the read handler doesn't read the data */		if (sp->handlerMask & SOCKET_READABLE && socketInputBuffered(sid) > 0) {			sp->currentEvents |= SOCKET_READABLE;		}	}/* *	If now writable and flushing in the background, continue flushing */	if (sp->currentEvents & SOCKET_WRITABLE) {		if (sp->flags & SOCKET_FLUSHING) {			rq = &sp->outBuf;			if (ringqLen(rq) > 0) {				socketFlush(sp->sid);			} else {				sp->flags &= ~SOCKET_FLUSHING;			}		}	}/* *	Now invoke the users socket handler. NOTE: the handler may delete the *	socket, so we must be very careful after calling the handler. */	if (sp->handler && (sp->handlerMask & sp->currentEvents)) {		(sp->handler)(sid, sp->handlerMask & sp->currentEvents, 			sp->handler_data);/* *		Make sure socket pointer is still valid, then reset the currentEvents. */ 		if (socketList && sid < socketMax && socketList[sid] == sp) {			sp->currentEvents = 0;		}	}	return 1;}/******************************************************************************//* *	Set the socket blocking mode */int socketSetBlock(int sid, int on){	socket_t		*sp;	unsigned long	flag;	int				iflag;	int				oldBlock;	flag = iflag = !on;	if ((sp = socketPtr(sid)) == NULL) {		a_assert(0);		return 0;	}	oldBlock = (sp->flags & SOCKET_BLOCK);	sp->flags &= ~(SOCKET_BLOCK);	if (on) {		sp->flags |= SOCKET_BLOCK;	}/* *	Put the socket into block / non-blocking mode */	if (sp->flags & SOCKET_BLOCK) {#if (defined (CE) || defined (WIN))		ioctlsocket(sp->sock, FIONBIO, &flag);#elif (defined (ECOS))		int off;		off = 0;		ioctl(sp->sock, FIONBIO, &off);#elif (defined (VXWORKS) || defined (NW))		ioctl(sp->sock, FIONBIO, (int)&iflag);#else		fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) & ~O_NONBLOCK);#endif	} else {#if (defined (CE) || defined (WIN))		ioctlsocket(sp->sock, FIONBIO, &flag);#elif (defined (ECOS))		int on;		on = 1;		ioctl(sp->sock, FIONBIO, &on);#elif (defined (VXWORKS) || defined (NW))		ioctl(sp->sock, FIONBIO, (int)&iflag);#else		fcntl(sp->sock, F_SETFL, fcntl(sp->sock, F_GETFL) | O_NONBLOCK);#endif	}	return oldBlock;}/******************************************************************************//* *	Return true if a readable socket has buffered data. - not public */int socketDontBlock(){	socket_t	*sp;	int			i;	for (i = 0; i < socketMax; i++) {		if ((sp = socketList[i]) == NULL || 				(sp->handlerMask & SOCKET_READABLE) == 0) {			continue;		}		if (socketInputBuffered(i) > 0) {			return 1;		}	}	return 0;}/******************************************************************************//* *	Return true if a particular socket buffered data. - not public */int socketSockBuffered(int sock){	socket_t	*sp;	int			i;	for (i = 0; i < socketMax; i++) {		if ((sp = socketList[i]) == NULL || sp->sock != sock) {			continue;		}		return socketInputBuffered(i);	}	return 0;}#endif /* (!WIN) | LITTLEFOOT | WEBS *//******************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -