stream.c
来自「《jsp编程起步》里面的所有源代码」· C语言 代码 · 共 796 行 · 第 1/2 页
C
796 行
/* * Copyright (c) 1999-2000 Caucho Technology. All rights reserved. * * Caucho Technology permits redistribution, modification and use * of this file in source and binary form ("the Software") under the * Caucho Developer Source License ("the License"). In particular, the following * conditions must be met: * * 1. Each copy or derived work of the Software must preserve the copyright * notice and this notice unmodified. * * 2. Redistributions of the Software in source or binary form must include * an unmodified copy of the License, normally in a plain ASCII text * * 3. The names "Resin" or "Caucho" are trademarks of Caucho Technology and * may not be used to endorse products derived from this software. * "Resin" or "Caucho" may not appear in the names of products derived * from this software. * * 4. Caucho Technology requests that attribution be given to Resin * in any manner possible. We suggest using the "Resin Powered" * button or creating a "powered by Resin(tm)" link to * http://www.caucho.com for each page served by Resin. * * This Software is provided "AS IS," without a warranty of any kind. * ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. * CAUCHO TECHNOLOGY AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE OR ANY THIRD PARTY AS A RESULT OF USING OR * DISTRIBUTING SOFTWARE. IN NO EVENT WILL CAUCHO OR ITS LICENSORS BE LIABLE * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE SOFTWARE, EVEN IF HE HAS BEEN ADVISED OF THE POSSIBILITY * OF SUCH DAMAGES. * * @author Scott Ferguson * * $Id: stream.c,v 1.29 2000/10/31 18:45:42 ferg Exp $ */#include <stdlib.h>#include <errno.h>#include <stdio.h>#include <string.h>#include <fcntl.h>#ifdef WIN32#include <winsock2.h>#else#include <sys/types.h>#include <sys/time.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <unistd.h>#endif#include "cse.h"#define DEFAULT_PORT 6802#define DEAD_TIME 120#define LIVE_TIME 10#define CONNECT_TIMEOUT 2static int g_count;voidcse_close(stream_t *s, char *msg){ int socket = s->socket; LOG(("close %d %s\n", s->socket, msg)); s->socket = -1; cse_kill_socket_cleanup(socket, s->web_pool); closesocket(socket);}#ifdef WIN32static intcse_connect(struct sockaddr_in *sin, srun_t *srun){ unsigned int sock; unsigned long is_nonblock; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { LOG(("mod_caucho can't create socket.\n")); return -1; /* bad socket */ } is_nonblock = 1; ioctlsocket(sock, FIONBIO, &is_nonblock); if (connect(sock, (struct sockaddr *) sin, sizeof(struct sockaddr_in))) { WSAEVENT event = WSACreateEvent(); WSANETWORKEVENTS networkResult; int result; WSAEventSelect(sock, event, FD_CONNECT); result = WSAWaitForMultipleEvents(1, &event, 0, srun->connect_timeout * 1000, 0); WSAEnumNetworkEvents(sock, event, &networkResult); WSAEventSelect(sock, 0, 0); WSACloseEvent(event); if (result != WSA_WAIT_EVENT_0 || networkResult.iErrorCode[FD_CONNECT_BIT] != NO_ERROR) { closesocket(sock); return -1; } } is_nonblock = 0; ioctlsocket(sock, FIONBIO, &is_nonblock); LOG(("connect")); return sock;}#elsestatic intcse_connect(struct sockaddr_in *sin, srun_t *srun){ int sock; fd_set write_fds; struct timeval timeout; int flags; int error = 0; int len = sizeof(error); sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { LOG(("mod_caucho can't create socket.\n")); return -1; /* bad socket */ } flags = fcntl(sock, F_GETFL); fcntl(sock, F_SETFL, O_NONBLOCK|flags); FD_ZERO(&write_fds); FD_SET(sock, &write_fds); timeout.tv_sec = srun->connect_timeout; timeout.tv_usec = 0; if (! connect(sock, (const struct sockaddr *) sin, sizeof(*sin))) { fcntl(sock, F_SETFL, flags); return sock; } else if (errno != EWOULDBLOCK && errno != EINPROGRESS) { LOG(("connect quickfailed %x %d %d\n", sin->sin_addr.s_addr, ntohs(sin->sin_port), errno)); close(sock); return -1; } else if (select(sock + 1, 0, &write_fds, 0, &timeout) <= 0) { LOG(("timeout %x %d %d\n", sin->sin_addr.s_addr, ntohs(sin->sin_port), errno)); fcntl(sock, F_SETFL, flags); close(sock); return -1; } else if (! FD_ISSET(sock, &write_fds) || getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error) { LOG(("connect failed %x %d %d\n", sin->sin_addr.s_addr, ntohs(sin->sin_port), errno)); close(sock); return -1; } else { fcntl(sock, F_SETFL, flags); LOG(("connect %x:%d -> %d\n", sin->sin_addr.s_addr, ntohs(sin->sin_port), sock)); return sock; }}#endifstatic intcse_connect_wait(struct sockaddr_in *sin){ int sock; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { LOG(("mod_caucho can't create socket.\n")); return -1; /* bad socket */ } if (! connect(sock, (const struct sockaddr *) sin, sizeof(*sin))) { return sock; } LOG(("cse_connect_wait can't connect %x %d %d\n", sin->sin_addr.s_addr, ntohs(sin->sin_port), errno)); closesocket(sock); return -1;}intcse_open(stream_t *s, config_t *config, srun_t *srun, void *web_pool, int wait){ struct sockaddr_in sin; s->config = config; s->update_count = config->update_count; s->pool = config->p; s->web_pool = web_pool; s->write_length = 0; s->read_length = 0; s->read_offset = 0; s->srun = srun; sin.sin_family = AF_INET; if (srun->host) sin.sin_addr = *srun->host; else sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); if (srun->port <= 0) srun->port = DEFAULT_PORT; sin.sin_port = htons((short) srun->port); if (wait || srun->connect_timeout <= 0) s->socket = cse_connect_wait(&sin); else s->socket = cse_connect(&sin, srun); return s->socket >= 0;}intcse_flush(stream_t *s){ int len; if (s->write_length > 0) { len = send(s->socket, s->write_buf, s->write_length, 0); if (len != s->write_length) return -1; s->write_length = 0; } return 0;}intcse_fill_buffer(stream_t *s){ if (s->socket < 0 || cse_flush(s) < 0) return -1; s->read_offset = 0; s->read_length = recv(s->socket, s->read_buf, BUF_LENGTH, 0); if (s->read_length <= 0) { cse_close(s, "fill_buffer"); return -1; } return s->read_length;}intcse_read_byte(stream_t *s){ if (s->read_offset >= s->read_length) { if (cse_fill_buffer(s) < 0) return -1; } return s->read_buf[s->read_offset++];}voidcse_write(stream_t *s, const char *buf, int length){ /* XXX: writev??? */ if (s->write_length + length > BUF_LENGTH) { if (s->write_length > 0) { int len; len = send(s->socket, s->write_buf, s->write_length, 0); s->write_length = 0; if (len < 0) { cse_close(s, "write"); return; } } if (length > BUF_LENGTH) { int len; len = send(s->socket, s->write_buf, s->write_length, 0); if (len < 0) cse_close(s, "write"); return; } } memcpy(s->write_buf + s->write_length, buf, length); s->write_length += length;}intcse_read_all(stream_t *s, char *buf, int len){ while (len > 0) { int sublen; if (s->read_offset >= s->read_length) { if (cse_fill_buffer(s) < 0) return -1; } sublen = s->read_length - s->read_offset; if (len < sublen) sublen = len; memcpy(buf, s->read_buf + s->read_offset, sublen); buf += sublen; len -= sublen; s->read_offset += sublen; } return 1;}intcse_skip(stream_t *s, int len){ while (len > 0) { int sublen; if (s->read_offset >= s->read_length) { if (cse_fill_buffer(s) < 0) return -1; } sublen = s->read_length - s->read_offset; if (len < sublen) sublen = len; len -= sublen; s->read_offset += sublen; } return 1;}intcse_read_limit(stream_t *s, char *buf, int buflen, int readlen){ int result; if (buflen >= readlen) { result = cse_read_all(s, buf, readlen); buf[readlen] = 0; } else { result = cse_read_all(s, buf, buflen); buf[buflen - 1] = 0; cse_skip(s, readlen - buflen); } return result;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?