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 + -
显示快捷键?