Ejemplo n.º 1
0
// read/write with call multiplexing
void task8(void* arg)
{
	static st_netfd_t rfd0 = st_open("/dev/random", O_RDONLY, S_IRUSR);
	static st_netfd_t rfd1 = st_open("/dev/urandom", O_RDONLY, S_IRUSR);
	static st_netfd_t rfd2 = st_open("/dev/zero", O_RDONLY, S_IRUSR);
	static st_netfd_t wfd = st_open("/dev/null", O_WRONLY, S_IWUSR);
	int rc = 0;
	static const int count = 10000;

	for (long i = 0; i < count; ++i) {
		if ((rc = st_read(rfd0, &rc, sizeof(rc), -1)) <= 0) {
			std::cout << "st_read " << rc << " " << strerror(rc) << std::endl;
			exit(1);
		}
		if ((rc = st_read(rfd1, &rc, sizeof(rc), -1)) <= 0) {
			std::cout << "st_read " << rc << " " << strerror(rc) << std::endl;
			exit(1);
		}
		if ((rc = st_read(rfd2, &rc, sizeof(rc), -1)) <= 0) {
			std::cout << "st_read " << rc << " " << strerror(rc) << std::endl;
			exit(1);
		}
		if ((rc = st_write(wfd, &rc, sizeof(rc), -1)) <= 0) {
			std::cout << "st_write " << rc << " " << strerror(rc) << std::endl;
			exit(1);
		}
	}
}
Ejemplo n.º 2
0
int SrsStSocket::read(void* buf, size_t size, ssize_t* nread)
{
    int ret = ERROR_SUCCESS;

    ssize_t nb_read = st_read(stfd, buf, size, recv_timeout);
    if (nread) {
        *nread = nb_read;
    }

    // On success a non-negative integer indicating the number of bytes actually read is returned
    // (a value of 0 means the network connection is closed or end of file is reached).
    // Otherwise, a value of -1 is returned and errno is set to indicate the error.
    if (nb_read <= 0) {
        // @see https://github.com/simple-rtmp-server/srs/issues/200
        if (nb_read < 0 && errno == ETIME) {
            return ERROR_SOCKET_TIMEOUT;
        }

        if (nb_read == 0) {
            errno = ECONNRESET;
        }

        return ERROR_SOCKET_READ;
    }

    recv_bytes += nb_read;

    return ret;
}
Ejemplo n.º 3
0
int SrsSocket::read(void* buf, size_t size, ssize_t* nread)
{
    int ret = ERROR_SUCCESS;

    ssize_t nb_read = st_read(stfd, buf, size, recv_timeout);
    if (nread) {
        *nread = nb_read;
    }

    // On success a non-negative integer indicating the number of bytes actually read is returned
    // (a value of 0 means the network connection is closed or end of file is reached).
    if (nb_read <= 0) {
        if (errno == ETIME) {
            return ERROR_SOCKET_TIMEOUT;
        }

        if (nb_read == 0) {
            errno = ECONNRESET;
        }

        return ERROR_SOCKET_READ;
    }

    recv_bytes += nb_read;

    return ret;
}
Ejemplo n.º 4
0
Archivo: pt_main.c Proyecto: xxvv/pt
static void *pt_sig_process(void *arg)
{
    int signo;

    for (;;) {
        /* Read the next signal from the signal pipe */
        st_read(_sig_pipe[0], &signo, sizeof(int), ST_UTIME_NO_TIMEOUT);

        switch (signo) {
            case SIGHUP:
                break;
            case SIGTERM:
                break;
            case SIGUSR1:
                pt_cmd_show();
                break;
            case SIGUSR2:
                pt_cmd_run();
                break;
            default:
                ;
        }
    }

    return NULL;
}
Ejemplo n.º 5
0
Archivo: pt_main.c Proyecto: xxvv/pt
void pt_shell()
{
    st_netfd_t fd_shell;
    char input[1024];
    int i;

    fd_shell = st_netfd_open(fileno(stdin));
    if (fd_shell == NULL) {
        printf("open stdin failed\n");
    }

    while (fd_shell) {
        printf(">>> ");
        fflush(stdout);
        st_read(fd_shell, input, sizeof(input), ST_UTIME_NO_TIMEOUT);
        if (strstr(input, "show"))
            pt_cmd_show();
        else if (strstr(input, "run"))
            pt_cmd_run();
        else if (strstr(input, "?"))
            pt_cmd_help();
        else
            printf("invalid cmd %s", input);
        printf("\n");
    }
}
Ejemplo n.º 6
0
hoxResult
hoxSocketAPI::read_nbytes( const st_netfd_t  fd,
                           const size_t      nBytes,
                           std::string&      sResult )
{
    /* Read a line until seeing N bytes */

    char     c;
    ssize_t  nRead = 0;

    for (;;)
    {
        nRead = st_read( fd, &c, sizeof(c), ST_UTIME_NO_TIMEOUT );
        if ( nRead == 1 )
        {
            sResult += c;
            if ( sResult.size() == nBytes )
            {
                break;   // Done.
            }
        }
        else
        {
            hoxLog(LOG_SYS_WARN, "%s: Fail to read 1 byte from the network", __FUNCTION__);
            hoxLog(LOG_WARN, "%s: Result message accumulated so far = [%s].", __FUNCTION__, sResult.c_str());
            return hoxRC_ERR;
        }
    }

    return hoxRC_OK;
}
Ejemplo n.º 7
0
Archivo: io.c Proyecto: 13916688528/srs
_st_netfd_t *st_accept(_st_netfd_t *fd, struct sockaddr *addr, int *addrlen, st_utime_t timeout)
{
    int osfd, err;
    _st_netfd_t *newfd;
    _st_netfd_t **p = (_st_netfd_t **) fd->aux_data;
    ssize_t n;
    char c;
    
    for ( ; ; ) {
        if (p == NULL) {
            osfd = accept(fd->osfd, addr, (socklen_t *)addrlen);
        } else {
            /* Get the lock */
            n = st_read(p[0], &c, 1, timeout);
            if (n < 0) {
                return NULL;
            }
            ST_ASSERT(n == 1);
            /* Got the lock */
            osfd = accept(fd->osfd, addr, (socklen_t *)addrlen);
            /* Unlock */
            err = errno;
            n = st_write(p[1], &c, 1, timeout);
            ST_ASSERT(n == 1);
            errno = err;
        }
        if (osfd >= 0) {
            break;
        }
        if (errno == EINTR) {
            continue;
        }
        if (!_IO_NOT_READY_ERROR) {
            return NULL;
        }
        /* Wait until the socket becomes readable */
        if (st_netfd_poll(fd, POLLIN, timeout) < 0) {
            return NULL;
        }
    }
    
    /* On some platforms the new socket created by accept() inherits */
    /* the nonblocking attribute of the listening socket */
#if defined (MD_ACCEPT_NB_INHERITED)
    newfd = _st_netfd_new(osfd, 0, 1);
#elif defined (MD_ACCEPT_NB_NOT_INHERITED)
    newfd = _st_netfd_new(osfd, 1, 1);
#else
    #error Unknown OS
#endif
    
    if (!newfd) {
        err = errno;
        close(osfd);
        errno = err;
    }
    
    return newfd;
}
Ejemplo n.º 8
0
Archivo: test.c Proyecto: zgbkny/ctoolx
/* ARGSUSED */
static void *process_signals(void *arg)
{
  int signo;

  for ( ; ; ) {
    /* Read the next signal from the signal pipe */
    if (st_read(sig_pipe[0], &signo, sizeof(int),
     ST_UTIME_NO_TIMEOUT) != sizeof(int))
      err_sys_quit(errfd, "ERROR: process %d (pid %d): signal processor:"
		   " st_read", my_index, my_pid);

    switch (signo) {
    case SIGHUP:
      err_report(errfd, "INFO: process %d (pid %d): caught SIGHUP,"
		 " reloading configuration", my_index, my_pid);
      if (interactive_mode) {
	load_configs();
	break;
      }
      /* Reopen log files - needed for log rotation */
      if (log_access) {
	logbuf_flush();
	logbuf_close();
	logbuf_open();
      }
      close(errfd);
      if ((errfd = open(ERRORS_FILE, O_CREAT | O_WRONLY | O_APPEND, 0644)) < 0)
	err_sys_quit(STDERR_FILENO, "ERROR: process %d (pid %d): signal"
		     " processor: open", my_index, my_pid);
      /* Reload configuration */
      load_configs();
      break;
    case SIGTERM:
      /*
       * Terminate ungracefully since it is generally not known how long
       * it will take to gracefully complete all client sessions.
       */
      err_report(errfd, "INFO: process %d (pid %d): caught SIGTERM,"
		 " terminating", my_index, my_pid);
      if (log_access)
	logbuf_flush();
      exit(0);
    case SIGUSR1:
      err_report(errfd, "INFO: process %d (pid %d): caught SIGUSR1",
		 my_index, my_pid);
      /* Print server info to stderr */
      dump_server_info();
      break;
    default:
      err_report(errfd, "INFO: process %d (pid %d): caught signal %d",
		 my_index, my_pid, signo);
    }
  }

  /* NOTREACHED */
  return NULL;
}
Ejemplo n.º 9
0
bool SMUSync::LoginPlat(st_netfd_t fd, const PlatLoginInfo& plat)
{
	DMXml xml;
	bool flag = true;
	std::string msg;
	char		RecvBuf[2048] = {};
	UINT32      RecvLen = 0;

	xml.NewRoot("soap:Envelope")
		->SetTextAttribute("xmlns:soap", "http://www.w3.org/2003/05/soap-envelope")
		->SetTextAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
		->SetTextAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema")
		->SetTextAttribute("xmlns:soapenc", "http://schemas.xmlsoap.org/soap/encoding/")
		->NewChild("soap:Body", 0)
		->NewChild("Authenticate", 0)
		->SetTextAttribute("xmlns","http://see1000.com/service")
		->NewChild("name", plat.PlatUserName.c_str())->GetParent()
		->NewChild("pass", plat.PlatPwd.c_str());
	std::string body = xml.Encode();

	//PacketPlatServer("Authenticate", body);

	do 
	{
		if (st_write(fd, msg.c_str(), msg.length(),-1)<0)
		{
			flag = true;
			break;
		}

		if (st_read(fd, RecvBuf, 2048, -1)<0)
		{
			flag = false;
			break;
		}

	/*	{
			std::string result = ParseWebService(RecvBuf, "AuthenticateResult");
			if(result.compare("true"))
			{
				return false;
			}
		}*/

	} while (0);

	return flag;
}
Ejemplo n.º 10
0
void task15(void* arg)
{
	st_netfd_t rfd = st_open("/Users/vss/projects/1.gz", O_RDONLY, S_IRUSR);
	st_netfd_t wfd = st_open("/Users/vss/projects/tmp.gz", O_WRONLY, S_IWUSR);

	for (long w = 0; w < 3; ++w) {
		char buffer[32096];
		const char str[] = "Of course, take it!";
		char response[1024 + sizeof(str)];
		int rc = 0;

		int c = 0;
		while (c < sizeof(buffer))
		{
			if ((rc = st_read(rfd, buffer + c, std::min<int>(4, sizeof(buffer) - c), -1)) <= 0) {
				std::cout << "st_read " << rc << " " << strerror(rc) << std::endl;
				exit(1);
			}
			c += rc;
		}

		if ((rc = st_mutex_lock(test4_mutex)) != 0) {
			std::cout << "st_mutex_lock " << rc << " " << strerror(rc) << std::endl;
			exit(1);
		}

		for (int i = 0; i < sizeof(response); i += sizeof(str))
		{
			memcpy(response + i, str, sizeof(str));
		}

		if ((rc = st_mutex_unlock(test4_mutex)) != 0) {
			std::cout << "st_mutex_unlock " << rc << " " << strerror(rc) << std::endl;
			exit(1);
		}

		if ((rc = st_write(wfd, response, sizeof(response), -1)) <= 0) {
			std::cout << "st_write " << rc << " " << strerror(rc) << std::endl;
			exit(1);
		}
	}

	st_netfd_close(rfd);
	st_netfd_close(wfd);
}
Ejemplo n.º 11
0
int SrsSignalManager::cycle()
{
    int ret = ERROR_SUCCESS;
    
    if (signal_read_stfd == NULL) {
        signal_read_stfd = st_netfd_open(sig_pipe[0]);
    }

    int signo;
    
    /* Read the next signal from the pipe */
    st_read(signal_read_stfd, &signo, sizeof(int), ST_UTIME_NO_TIMEOUT);
    
    /* Process signal synchronously */
    _server->on_signal(signo);
    
    return ret;
}
Ejemplo n.º 12
0
Archivo: test.c Proyecto: zgbkny/ctoolx
/*
 * Session handling function stub. Just dumps small HTML page.
 */
void handle_session(long srv_socket_index, st_netfd_t cli_nfd)
{
  static char resp[] = "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n"
                       "Connection: close\r\n\r\n<H2>It worked!</H2>\n";
  char buf[512];
  int n = sizeof(resp) - 1;
  struct in_addr *from = st_netfd_getspecific(cli_nfd);

  if (st_read(cli_nfd, buf, sizeof(buf), SEC2USEC(REQUEST_TIMEOUT)) < 0) {
    err_sys_report(errfd, "WARN: can't read request from %s: st_read",
		   inet_ntoa(*from));
    return;
  }
  if (st_write(cli_nfd, resp, n, ST_UTIME_NO_TIMEOUT) != n) {
    err_sys_report(errfd, "WARN: can't write response to %s: st_write",
		   inet_ntoa(*from));
    return;
  }

  RQST_COUNT(srv_socket_index)++;
}
Ejemplo n.º 13
0
int main() {
	int i=0;
	char buffer[4096], byte;
	
	//fread(<#void *#>, <#size_t #>, <#size_t #>, <#FILE *#>)
	//st_read(<#st_netfd_t fd#>, <#void *buf#>, <#size_t nbyte#>, <#st_utime_t timeout#>)
	
	/*
	while ((fread(&byte,1,1,stdin))) {
		if (byte=='\n') break;
		buffer[i]=byte; 
		i++;
	}
	 */
	
	st_read(stdin, &byte, 1, 1000);
	
	buffer[i+1]='\0'; /* null terminate */
	printf("You entered: \"%s\"\n",buffer);
	return 0;
}
Ejemplo n.º 14
0
int							ft_serve(void)
{
	t_ctx					*ctx;
	int						cs;
	unsigned int			cslen;
	struct sockaddr_in		csin;
	int						father;

	ctx = ft_ctx();
	if (-1 == (cs = accept(ctx->sock, (struct sockaddr *)&csin, &cslen)))
		return (ft_error("Cant accept connexions"));
	ctx->cs = cs;
	ft_success("Client connected !");
	father = fork();
	if (!father)
	{
		if (ERR == st_read(cs))
			return (ERR);
	}
	else
		ft_serve();
	return (OK);
}
Ejemplo n.º 15
0
void *handle_conn(void *arg) {
  st_netfd_t client;
  client = (st_netfd_t)arg;
  arg = NULL;

  char buff[1024];
  int len = sizeof(buff) / sizeof(buff[0]);

  int received;

  received = st_read(client, buff, len, ST_UTIME_NO_TIMEOUT);

  // fprintf(stdout, "%s\n", buff);
  st_netfd_t STDOUT;
  STDOUT = st_netfd_open(STDOUT_FILENO);

  st_write(STDOUT, buff, sizeof(buff), ST_UTIME_NO_TIMEOUT);

  received = st_write(client, buff, received, ST_UTIME_NO_TIMEOUT);

  st_netfd_close(client);

  return 0;
}
Ejemplo n.º 16
0
int pushto(st_netfd_t rmt_nfd, struct thr_data *td)
{
  FILE *in;
  char buffer[BUFSIZ];
  struct stat st;
  int filesize;
  int i, len;
  struct q_info *q = td->q;
  char *basename;
  
  if ((basename = strrchr(td->filename, '/')) == NULL) {
    basename = td->filename;
  } else {
    basename++;
  }
  if (stat(td->filename, &st)) {
    LOG(LOG_WARNING, "%s: %m", td->filename);
    return 0;
  }
  filesize = (int) st.st_size;
  if (filesize == 0) {
    LOG(LOG_WARNING, "zero size: %s", td->filename);
    return 1;
  }

  // expect: +OK UpWatch Acceptor vx.xx. Please login
  memset(buffer, 0, sizeof(buffer));
  len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT);
  if (len == -1) {
    if (errno == ETIME) { 
      LOG(LOG_WARNING, "timeout reading login request string"); 
    } else { 
      LOG(LOG_WARNING, "read: %m"); 
    }
    return 0;
  }
  if (debug > 3) fprintf(stderr, "%s[%u] < %s", q->host, st_netfd_fileno(rmt_nfd), buffer);
  if (buffer[0] != '+') {
    LOG(LOG_WARNING, buffer);
    return 0;
  } 

  sprintf(buffer, "USER %s\n", q->user);
  uw_setproctitle("%s:%d %s", q->host, q->port, buffer);
  if (debug > 3) fprintf(stderr, "%s[%u] > %s", q->host, st_netfd_fileno(rmt_nfd), buffer);
  len = st_write(rmt_nfd, buffer, strlen(buffer), TIMEOUT);
  if (len == -1) {
    if (errno == ETIME) { 
      LOG(LOG_WARNING, "timeout writing %s", buffer); 
    } else { 
      LOG(LOG_WARNING, "write: %m"); 
    }
    return 0;
  }

  // expect here: +OK Please enter password
  memset(buffer, 0, sizeof(buffer));
  len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT);
  if (len == -1) {
    if (errno == ETIME) { 
      LOG(LOG_WARNING, "timeout reading OK enter password"); 
    } else { 
      LOG(LOG_WARNING, "read: %m"); 
    }
    return 0;
  }
  if (debug > 3) fprintf(stderr, "%s[%u] < %s", q->host, st_netfd_fileno(rmt_nfd), buffer);
  if (buffer[0] != '+') {
    LOG(LOG_WARNING, buffer);
    return 0;
  } 

  sprintf(buffer, "PASS %s\n", q->pwd);
  uw_setproctitle("%s:%d PASS xxxxxxxx", q->host, q->port);
  if (debug > 3) fprintf(stderr, "%s[%u] > %s", q->host, st_netfd_fileno(rmt_nfd), buffer);
  len = st_write(rmt_nfd, buffer, strlen(buffer), TIMEOUT);
  if (len == -1) {
    if (errno == ETIME) { 
      LOG(LOG_WARNING, "timeout writing %s", buffer); 
    } else { 
      LOG(LOG_WARNING, "write: %m"); 
    }
    return 0;
  }

  // expect here: +OK logged in, enter command
  memset(buffer, 0, sizeof(buffer));
  len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT);
  if (len == -1) {
    if (errno == ETIME) { 
      LOG(LOG_WARNING, "timeout reading enter command"); 
    } else { 
      LOG(LOG_WARNING, "read: %m"); 
    }
    return 0;
  }
  if (debug > 3) fprintf(stderr, "%s[%u] < %s", q->host, st_netfd_fileno(rmt_nfd), buffer);
  if (buffer[0] != '+') {
    LOG(LOG_WARNING, buffer);
    return 0;
  } 

  sprintf(buffer, "DATA %d %s\n", filesize, basename);
  uw_setproctitle("%s:%d %s", q->host, q->port, buffer);
  if (debug > 3) fprintf(stderr, "%s[%u] > %s", q->host, st_netfd_fileno(rmt_nfd), buffer);
  len = st_write(rmt_nfd, buffer, strlen(buffer), TIMEOUT);
  if (len == -1) {
    if (errno == ETIME) { 
      LOG(LOG_WARNING, "timeout writing %s", buffer); 
    } else { 
      LOG(LOG_WARNING, "write: %m"); 
    }
    return 0;
  }

  // expect here: +OK start sending your file
  memset(buffer, 0, sizeof(buffer));
  len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT);
  if (len == -1) {
    if (errno == ETIME) { 
      LOG(LOG_WARNING, "timeout reading DATA response"); 
    } else { 
      LOG(LOG_WARNING, "read: %m"); 
    }
    return 0;
  }
  if (debug > 3) fprintf(stderr, "%s[%u] < %s", q->host, st_netfd_fileno(rmt_nfd), buffer);
  if (buffer[0] != '+') {
    LOG(LOG_WARNING, buffer);
    return 0;
  } 

  if ((in = fopen(td->filename, "r")) == NULL) {
    LOG(LOG_ERR, "can't open %s", td->filename);
    return 0;
  }

  uw_setproctitle("%s:%d: UPLOADING, size=%u %s", q->host, q->port,
                filesize, td->filename);
  while ((i = fread(buffer, 1, sizeof(buffer), in)) == sizeof(buffer)) {
    //LOG(LOG_DEBUG, "read %d from input", i);
    len = st_write(rmt_nfd, buffer, i, TIMEOUT);
    if (len == -1) {
      if (errno == ETIME) { 
        LOG(LOG_WARNING, "timeout writing %s", buffer); 
      } else { 
        LOG(LOG_WARNING, "write: %m"); 
      }
      fclose(in);
      return 0;
    }
    //LOG(LOG_DEBUG, "written %d to output", len);
  }

  if (!feof(in)) {
    LOG(LOG_ERR, "fread: %m");
    fclose(in);
    return 0;
  }
  if (i>0 && st_write(rmt_nfd, buffer, i, TIMEOUT) != i) {
    LOG(LOG_ERR, "socket write error: %m");
    fclose(in);
    return 0;
  }
  fclose(in);

  // expect here: +OK Thank you. Enter command
  memset(buffer, 0, sizeof(buffer));
  len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT);
  if (len == -1) {
    if (errno == ETIME) { 
      LOG(LOG_WARNING, "timeout reading enter command"); 
    } else { 
      LOG(LOG_WARNING, "read: %m"); 
    }
    return 0;
  }
  if (debug > 3) fprintf(stderr, "%s[%u] < %s", q->host, st_netfd_fileno(rmt_nfd), buffer);
  if (buffer[0] != '+') {
    LOG(LOG_WARNING, buffer);
    return 0;
  } 

  sprintf(buffer, "QUIT\n");
  uw_setproctitle("%s:%d %s", q->host, q->port, buffer);
  if (debug > 3) fprintf(stderr, "%s[%u] > %s", q->host, st_netfd_fileno(rmt_nfd), buffer);
  len = st_write(rmt_nfd, buffer, strlen(buffer), TIMEOUT);
  if (len == -1) {
    if (errno == ETIME) { 
      LOG(LOG_WARNING, "timeout writing %s", buffer); 
    } else { 
      LOG(LOG_WARNING, "write: %m"); 
    }
    return 0;
  }

  // expect here: +OK Nice talking to you. Bye
  memset(buffer, 0, sizeof(buffer));
  len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT);
  if (len == -1) {
    if (errno == ETIME) { 
      LOG(LOG_WARNING, "timeout reading QUIT response", buffer); 
    } else { 
      LOG(LOG_WARNING, "read: %m"); 
    }
    return 0;
  }
  if (debug > 3) fprintf(stderr, "%s[%u] < %s", q->host, st_netfd_fileno(rmt_nfd), buffer);
  return 1;
}
Ejemplo n.º 17
0
static void *handle_clientconn(void *arg) {
  st_netfd_t client = *(st_netfd_t*)arg;
  arg = NULL;

  // 握手
  // rpc客户端连入后,会主动发来客户端自己的 index
  // 长度为 1 字节
  char    buf[4096];
  ssize_t  len;

  // 先只读取 1 字节的客户端握手头,表示客户端自己的 index
  if ((len = st_read(client, buf, 1, ST_UTIME_NO_TIMEOUT)) < 0) {
    fprintf(stderr, "[%d] failed to handshake from client #%d: %s\n", my_index, *buf, strerror(errno));
    goto close_fd_and_quit;
  } else if (len == 0) {
    goto close_fd_and_quit;
  }

  uint8_t   client_index = (uint8_t)buf[0];

  fprintf(stdout, "[%d] 来自 rpc 客户端 #%d 的握手已经成功建立\n", my_index, client_index);

  // 如果 client_index 等于自己的 my_index,则这个有问题
  if (client_index == my_index) {
    fprintf(stderr, "[%d] rpc client promet the same index with mine.\n", my_index);
    goto close_fd_and_quit;
  }

  // 将客户端 fd 放入属于它 index 的 fd_list 内
  // 在前面的 make link to peers 当中,已经把写去远程结点的 st_netfd_t 保存于 fd_list 之内了
  // 所以不需要需要将远程连入的 st_netfd_t 保存在自己的 fd_list
  /*if (fd_list[client_index] != NULL) {
    fprintf(stderr, "[%d] This client #%d has connected before, replace it.\n", my_index, client_index);
    st_netfd_close(fd_list[client_index]);
  }
  fd_list[client_index] = client;*/

  // 初始化用于读取流的包结构
  struct rpc_package package;
  memset((void*)&package, 0, sizeof(package));

  const size_t pkghead_len = sizeof(rpcpkg_len);
  size_t      receive;
  size_t      cursor; // 记录数据偏移到了 buf 的什么位置

  // 循环服务处理
  for (;;) {
    if ((len = st_read(client, buf, sizeof(buf), ST_UTIME_NO_TIMEOUT)) < 0) {
      fprintf(stderr, "[%d] failed when read from client #%d.\n", my_index, client_index);
      goto close_fd_and_quit;
    } else if (len == 0) {
      goto close_fd_and_quit;
    } else {
      if (len > sizeof(buf))
        fprintf(stdout, "[%d] read %d bytes into buffer with size: %d bytes.\n", my_index, len, sizeof(buf));

      // 流进来数据了
      cursor = 0;
      while (cursor < len) { // 如果缓冲区内数据没有处理完

        // 如果之前没切过包,或者前一包已经完成
        if (package.total == package.received) {
          package.total = NTOH(*(rpcpkg_len *)(buf + cursor));

          if (len - cursor - pkghead_len >= package.total) {
            package.received = package.total;
          } else {
            package.received = len - cursor - pkghead_len;
          }

          memcpy(&package.data, buf + cursor + pkghead_len, package.received);

          cursor += package.received + pkghead_len;
        } else {
          // 现在处理的是断开包
          assert(package.received < package.total);

          receive = (len >= package.total - package.received) ? package.total - package.received : len;

          memcpy(&package.data + package.received, buf + cursor, receive);

          package.received += receive;
          cursor += receive;
        }

        // 如果刚刚处理过的包已经是完整包,则处决它
        if (package.received == package.total) {
          fprintf(stdout, "[%d] receive an rpc request with content: %s\n", my_index, package.data);
          // TODO: 添加收到 rpc 包的业务处理
        }
      }
    }
  }

close_fd_and_quit:
  st_netfd_close(client);
  return 0;
}
Ejemplo n.º 18
0
hoxResult
hoxDbClient::WWW_authenticate( const std::string& sPlayerId,
                               const std::string& sHPassword )
{
    const char* FNAME = "hoxDbClient::WWW_authenticate";
    hoxResult result = hoxRC_ERR;

    hoxLog(LOG_DEBUG, "%s: ENTER. pid = [%s].", FNAME, sPlayerId.c_str());

    /* Open the socket connect to the server. */

    const char* szHost = WWW_HOST;
    const int   nPort  = WWW_PORT;
    st_netfd_t  nfd    = NULL;

    nfd = _open_client_socket( szHost, nPort );
    if ( nfd == NULL )
    {
        hoxLog(LOG_ERROR, "%s: Failed to open a client socket to [%s:%d].", FNAME, szHost, nPort);
        return hoxRC_ERR;
    }

    /* Send the request. */

    std::string sRequest;

    sRequest = std::string("GET /blog/hoxchess-login.php")
                + "?pid="      + sPlayerId 
                + "&password="******" HTTP/1.0\r\n"
             + "Host: " + szHost + "\r\n"
             + "Content-Length: 0\r\n"
             + "\r\n";

    const int nToSend = sRequest.size();
    ssize_t   nSent = 0;

    hoxLog(LOG_DEBUG, "%s: Sending (%d bytes): [\n%s]...", FNAME, sRequest.size(), sRequest.c_str());
    nSent = st_write( nfd, 
                      sRequest.c_str(), 
                      nToSend, 
                      ST_UTIME_NO_TIMEOUT );
    if ( nSent < nToSend )
    {
        hoxLog(LOG_SYS_WARN, "%s: Failed to write to socket", FNAME);
        st_netfd_close( nfd );
        return hoxRC_OK;
    }

    /* Read the response back. */

    hoxLog(LOG_DEBUG, "%s: Reading response...", FNAME);
    std::string sResponse;
    ssize_t     nRead = 0;
    const int   MAX_TO_READ = 512;  // *** Hard-coded max-buffer-size.
    char        szBuffer[MAX_TO_READ];

    for (;;)
    {
        memset( szBuffer, 0, MAX_TO_READ );  // zero-out.
        nRead = st_read( nfd, szBuffer, MAX_TO_READ, ST_UTIME_NO_TIMEOUT );
        if ( nRead > 0 )
        {
            sResponse.append( szBuffer, nRead ); 
        }
        else if ( nRead != MAX_TO_READ )  // Connection closed?
        {
            break; // Done
        }
    }

    hoxLog(LOG_DEBUG, "%s: Received (%d bytes): [\n%s].", FNAME, sResponse.size(), sResponse.c_str());

    /* Check for return-code. */

    std::string::size_type npBody = sResponse.find("\r\n\r\n");

    if (   npBody != std::string::npos
        && sResponse.substr(npBody+4).find_first_of('0') == 0 )
    {
        result = hoxRC_OK;
    }

    /* Cleanup and return. */

    st_netfd_close( nfd );
    return result;
}
Ejemplo n.º 19
0
static void *handle_request(void *arg)
{
  struct pollfd pds[2];
  st_netfd_t cli_nfd, rmt_nfd;
  int sock, n;
  char buf[IOBUFSIZE];

  cli_nfd = (st_netfd_t) arg;
  pds[0].fd = st_netfd_fileno(cli_nfd);
  pds[0].events = POLLIN;

  /* Connect to remote host */
  if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
    print_sys_error("socket");
    goto done;
  }
  if ((rmt_nfd = st_netfd_open_socket(sock)) == NULL) {
    print_sys_error("st_netfd_open_socket");
    close(sock);
    goto done;
  }
  if (st_connect(rmt_nfd, (struct sockaddr *)&rmt_addr,
		 sizeof(rmt_addr), -1) < 0) {
    print_sys_error("st_connect");
    st_netfd_close(rmt_nfd);
    goto done;
  }
  pds[1].fd = sock;
  pds[1].events = POLLIN;

  /* Now just pump the data through */
  for ( ; ; ) {
    pds[0].revents = 0;
    pds[1].revents = 0;

    if (st_poll(pds, 2, -1) <= 0) {
      print_sys_error("st_poll");
      break;
    }

    if (pds[0].revents & POLLIN) {
      if ((n = (int) st_read(cli_nfd, buf, IOBUFSIZE, -1)) <= 0)
        break;
      if (st_write(rmt_nfd, buf, n, -1) != n)
        break;
    }

    if (pds[1].revents & POLLIN) {
      if ((n = (int) st_read(rmt_nfd, buf, IOBUFSIZE, -1)) <= 0)
        break;
      if (st_write(cli_nfd, buf, n, -1) != n)
        break;
    }
  }
  st_netfd_close(rmt_nfd);

done:

  st_netfd_close(cli_nfd);

  return NULL;
}
Ejemplo n.º 20
0
void *probe(void *data) 
{ 
  int sock, len;
  struct sockaddr_in rmt;
  st_netfd_t rmt_nfd;
  struct probedef *probe = (struct probedef *)data;
  char buffer[1024];
  st_utime_t start;

  ST_INITIATE(110);

  start = st_utime();

  if (debug > 3) fprintf(stderr, "Connecting to: %s\n", probe->ipaddress);
  if (st_connect(rmt_nfd, (struct sockaddr *)&rmt, sizeof(rmt), TIMEOUT) < 0) {
    char buf[256];

    sprintf(buf, "%s(%d): %s", probe->ipaddress, __LINE__, strerror(errno));
    probe->connect = ((float) (st_utime() - start)) * 0.000001;
    probe->msg = strdup(buf);
    LOG(LOG_DEBUG, probe->msg);
    if (debug > 3) fprintf(stderr, "%s: %s\n", probe->ipaddress, probe->msg);
    goto err_close;
  }
  probe->connect = ((float) (st_utime() - start)) * 0.000001;

  // expect here: +OK POP3 xxx.xxxxxxx.xx v2000.70rh server ready
  memset(buffer, 0, sizeof(buffer));
  len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT);
  if (len == -1) {
    ST_ERROR("read", TIMEOUT);
    goto err_close;
  }
  if (debug > 3) fprintf(stderr, "< %s", buffer);
  if (buffer[0] != '+') {
    probe->msg = strdup(buffer);
    goto err_close;
  }
  if (probe->username == NULL || probe->username[0] == 0) {
    probe->msg = strdup("missing username");
    goto err_close;
  }

  sprintf(buffer, "USER %s\n", probe->username);
  if (debug > 3) fprintf(stderr, "> %s", buffer);
  len = st_write(rmt_nfd, buffer, strlen(buffer), TIMEOUT);
  if (len == -1) {
    ST_ERROR("write", TIMEOUT);
    goto err_close;
  }

  // expect here: +OK User name accepted, password please
  memset(buffer, 0, sizeof(buffer));
  len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT);
  if (len == -1) {
    ST_ERROR("read", TIMEOUT);
    goto err_close;
  }
  if (debug > 3) fprintf(stderr, "< %s", buffer);
  if (buffer[0] != '+') {
    probe->msg = strdup(buffer);
    goto err_close;
  }

  sprintf(buffer, "PASS %s\n", probe->password);
  if (debug > 3) fprintf(stderr, "> %s", buffer);
  len = st_write(rmt_nfd, buffer, strlen(buffer), TIMEOUT);
  if (len == -1) {
    ST_ERROR("write", TIMEOUT);
    goto err_close;
  }

  // expect here: +OK Mailbox open, 62 messages
  memset(buffer, 0, sizeof(buffer));
  len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT);
  if (len == -1) {
    ST_ERROR("read", TIMEOUT);
    goto err_close;
  }
  if (debug > 3) fprintf(stderr, "< %s", buffer);
  if (buffer[0] != '+') {
    probe->msg = strdup(buffer);
    goto err_close;
  }

  sprintf(buffer, "QUIT\n");
  if (debug > 3) fprintf(stderr, "> %s", buffer);
  len = st_write(rmt_nfd, buffer, strlen(buffer), TIMEOUT);
  if (len == -1) {
    ST_ERROR("write", TIMEOUT);
    goto err_close;
  }

  // expect here: +OK Sayonara
  memset(buffer, 0, sizeof(buffer));
  len = st_read(rmt_nfd, buffer, sizeof(buffer), TIMEOUT);
  if (len == -1) {
    ST_ERROR("read", TIMEOUT);
    goto err_close;
  }
  if (debug > 3) fprintf(stderr, "< %s", buffer);
  if (buffer[0] != '+') {
    probe->msg = strdup(buffer);
    goto err_close;
  }

err_close:
  st_netfd_close(rmt_nfd);
  probe->total = ((float) (st_utime() - start)) * 0.000001;

done:
  thread_count--;
  return NULL;
}
Ejemplo n.º 21
0
/*---------------------------------------------------------------------------
 * Returns -1 on error, otherwise returns the ID of the command.
 *--------------------------------------------------------------------------*/
int 
recv_scsi_command(char *buffer)
{
#ifdef DIXTRAC_LINUX_SG
  int status = 0;

#ifdef LINUX_SG_IO
  sg_io_hdr_t sgio_hdr;
  int i;
#else
  char *buf_pointer;
  struct sg_header *sg_hd;
#endif

#ifndef SG_TIMER  
  struct timeval stop;
  struct timezone tz;
#endif
  
#ifdef SG_NONBLOCKING
#ifdef STATE_THREADS
#else
/* timeout in miliseconds */
#define TIMEOUT         5000  
  struct pollfd ufd;
  int rc;

  ufd.fd = scsidev_fd;
  ufd.events = POLLPRI | POLLIN;
  if ( 1 > (rc = poll(&ufd,1,TIMEOUT))) {
    if (rc == 0) {
      fprintf(stderr,"Disk timed out\n");
      return(-1);
    }
    else {
      error_handler("Error with poll syscall %s\n","");
    }
  }
#endif
#endif
#ifdef LINUX_SG_IO
  sgio_hdr.flags = SG_FLAG_DIRECT_IO; 
#ifdef STATE_THREADS
  status = st_read(scsidev_fd, &sgio_hdr, sizeof(sg_io_hdr_t),ST_TIMEOUT);
#else
  status = read(scsidev_fd, &sgio_hdr, sizeof(sg_io_hdr_t));
#endif
#else
  buf_pointer = buffer - SG_HDR_OFFSET; 
  sg_hd = (struct sg_header *) buf_pointer;
  /*  sg_hd->pack_id = cmd_id; */

  /* retrieve result */
  status = read(scsidev_fd, buf_pointer, SG_BIG_BUFF);
#endif

#ifndef SG_TIMER
  gettimeofday(&stop,&tz);
  ustop_sec = stop.tv_sec;
  /* ustop = (ustop_sec - ustart_sec)*1000000 + stop.tv_usec; */
  ustop = stop.tv_usec;
#else
#ifdef LINUX_SG_IO
  //  printf("%s() (%d,%d)\n", __func__, sgio_hdr.duration.tv_sec,
  // sgio_hdr.duration.tv_usec);


  ustop = sgio_hdr.duration.tv_usec;
  ustop_sec = sgio_hdr.duration.tv_sec;
#else
  ustop = sg_hd->time.tv_usec;
  ustop_sec = sg_hd->time.tv_sec;
#endif
#endif  

#ifdef LINUX_SG_IO  
  /*  printf("Time returned from sgio driver: %d ms\n",sgio_hdr.duration); */
  if ( status < 0 || (status < sizeof(sg_io_hdr_t))) {
    /* some error happened */
    fprintf( stderr, "read(sg_io) status = 0x%x\n", status);
    fprintf( stderr, "Sense buffer: ");
    for(i=0 ; i<sgio_hdr.sb_len_wr ; i++) 
      fprintf( stderr,"%x ",sense_buffer[i]);
    fprintf( stderr,"\n");
  }
  return(sgio_hdr.pack_id);
#else
  if ( status < 0 || sg_hd->result ) {
    /* some error happened */
    fprintf( stderr, "read(generic) status = 0x%x, result = 0x%x\n",
	     status, sg_hd->result);
    fprintf( stderr, "read(generic) sense "
	     "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
	     sg_hd->sense_buffer[0],         sg_hd->sense_buffer[1],
	     sg_hd->sense_buffer[2],         sg_hd->sense_buffer[3],
	     sg_hd->sense_buffer[4],         sg_hd->sense_buffer[5],
	     sg_hd->sense_buffer[6],         sg_hd->sense_buffer[7],
	     sg_hd->sense_buffer[8],         sg_hd->sense_buffer[9],
	     sg_hd->sense_buffer[10],        sg_hd->sense_buffer[11],
	     sg_hd->sense_buffer[12],        sg_hd->sense_buffer[13],
	     sg_hd->sense_buffer[14],        sg_hd->sense_buffer[15]);
    if (status < 0)
      error_handler("recv_scsi_command: Read error (%s)\n",strerror(errno));
  }
  else 
    /* buffer should already have all the necessarry data */
    /* just adjust the number of bytes returned */
    status -= SG_HDR_OFFSET;
  return (sg_hd->pack_id);
#endif

/* DIXTRAC_LINUX_SG */
#endif

#ifdef DIXTRAC_FREEBSD_CAM
  return(0);
#endif

}
Ejemplo n.º 22
0
int
hoxSocketAPI::read_until_all( const st_netfd_t   fd,
                              const std::string& sWanted,
                              std::string&       sOutput,
                              const int          timeout /* = -1 */ )
{
    const unsigned int nMax = 10 * 1024;  // 10-K limit

    sOutput.clear();

    char         c;         // The byte just received.
    const size_t requiredSeen = sWanted.size();
    size_t       currentSeen  = 0;
    int          iResult      = 0;
    int          nTotal       = 0; // Total bytes received so far.

    const st_utime_t timeout_usecs = ( timeout == -1 ? ST_UTIME_NO_TIMEOUT
                                                     : SEC2USEC( timeout ) );

    hoxCHECK_MSG(sizeof(char) == 1, HOX_ERR_SOCKET_OTHER, "size of char != 1");

    /* Receive data until seeing all characters in the "wanted" string
    * or until the peer closes the connection
    */
    while ( currentSeen < requiredSeen )
    {
        iResult = st_read( fd, &c, 1, timeout_usecs );
        if ( iResult == 1 )
        {
            sOutput += c;
            if ( c == sWanted[currentSeen] ) // seen the next char?
            {
                ++currentSeen;
                continue;
            }

            currentSeen = 0;  // Reset "what we have seen".

            if ( sOutput.size() >= nMax )  // Impose some limit.
            {
                hoxLog(LOG_WARN, "%s: *WARN* Max message's size [%d] reached.",
                    __FUNCTION__, nMax);
                return HOX_ERR_SOCKET_LIMIT;
            }
        }
        else if ( iResult == 0 ) // Connection closed?
        {
            return HOX_ERR_SOCKET_CLOSED;
        }
        else // Some other socket error?
        {
            if ( errno == EINTR )  // The current thread was interrupted
            {
                continue;
            }
            else if ( errno == ETIME    ) // The timeout occurred and no data was read
            {
                hoxLog(LOG_DEBUG, "%s: Timeout [%d secs].", __FUNCTION__, timeout);
                return HOX_ERR_SOCKET_TIMEOUT;
            }
            else
            {
                hoxLog(LOG_SYS_WARN, "%s: st_read failed", __FUNCTION__);
                return HOX_ERR_SOCKET_OTHER;
            }
        }
    }

    /* Chop off 'want' string. */
    if ( currentSeen == requiredSeen && requiredSeen > 0 )
    {
        nTotal = sOutput.size();
        sOutput = sOutput.substr(0, nTotal - requiredSeen);
    }

    return nTotal; // Return the number of bytes received.
}
Ejemplo n.º 23
0
void *
handle_connection(void *fd2)
{
    int rc, n, len;
    int ffd;
    char *buf, *fn;
    int i;

    st_netfd_t fd = (st_netfd_t)fd2;

    buf = malloc(4096);
    rc = 0;

 again:
    rc += st_read(fd, buf + rc, 4096 - rc,-1);
    if(rc < 0) { perror("st_read"); goto fail; }

    if(rc < 4)
        goto fail;

    if(memcmp(buf, "GET ", 4) != 0)
        goto fail;

    for(i = 5; i < rc; i++)
        if(buf[i] == ' ' || buf[i] == '\r' || buf[i] == '\n')
            break;
    if(i == rc && rc < 4096)
        goto again;

    len = strlen(root);

    fn = malloc(len + 1 + i - 5 + 12);
    strcpy(fn, root);
    memcpy(fn + len, buf + 5, i - 5);

    if(buf[i - 1] == '/')
        strcpy(fn + len + i - 5, "index.html");
    else
        fn[len + i - 5] = '\0';

    i--;

 search:
    while(i < rc - 3)
      if(buf[i++] == '\r' && buf[i] == '\n'){
        i++; if(buf[i++] == '\r' && buf[i] == '\n')
          goto send;
      }

    if(rc < 4096) {
        rc += st_read(fd, buf + rc, 4096 - rc,-1);
        goto search;
    }

 send:
#ifdef STATIC
    rc = st_write(fd, &resp, resp_size, 60000000);
    if(rc != resp_size) { perror("st_write"); goto fail; }
#else
    ffd = open(fn, O_RDONLY,0);
    if(ffd < 0) {
        int err;
        char *message;
        if(errno == ENOENT) {
            err = 404;
            message = "File doesn't exist";
        } else if(errno == EACCES || errno == EPERM) {
            err = 403;
            message = "Forbidden";
        } else if(errno == EMFILE || errno == ENFILE) {
            err = 500;
            message = "Out of file descriptors";
        } else if(errno == ENOMEM) {
            err = 500;
            message = "Out of memory";
        } else {
            err = 500;
            message = "Unknown error";
        }
        n = snprintf(buf, 4096,
                     "HTTP/1.1 %d %s\r\n"
                     "Content-Type: text/html\r\n"
                     "Server: Trivial-st\r\n"
                     "Connection: close\r\n"
                     "\r\n"
                     "<html><body><p>Couldn't open %s: %s</body></html>\r\n",
                     err, message, fn, message);
        free(fn);
    } else {
        free(fn);
        n = snprintf(buf, 4096,
                     "HTTP/1.1 200 OK\r\n"
                     "Content-Type: text/html\r\n"
                     "Server: Trivial-st\r\n"
                     "Connection: close\r\n"
                     "\r\n");
        rc = read(ffd, buf + n, 4096 - n);
        if(rc >= 0)
            n += rc;
    }

    rc = st_write(fd, buf, n,-1);
    if(rc < 0) { perror("write"); if(ffd >= 0) close(ffd); goto fail; }

    if(ffd >= 0) {
        while(1) {
            n = read(ffd, buf, 4096);
            if(n <= 0) break;
            rc = st_write(fd, buf, 4096,-1);
            st_sleep(0);
        }
    }

    close(ffd);
#endif

 fail:
    st_netfd_close(fd);
    free(buf);
    st_thread_exit(NULL);
}
Ejemplo n.º 24
0
int SMUSync::ReadInfo(st_netfd_t fd, std::string& body)
{

	int total_len = 0;
	int read_len = 0;
	std::string WebInfo ;
	{
		char buf[2049] = {};
		read_len = st_read(fd, buf, 2047, -1);
		if(read_len < 0)
		{
			return false;
		}

		WebInfo.clear();
		WebInfo = buf;
	}

	UINT32 headlen = 0;
	UINT32 bodylen = 0;
	INT32 body_pos = WebInfo.find("\r\n\r\n");
	if(body_pos > 0)
	{
		std::string header = WebInfo.substr(0, body_pos);
		headlen = header.size();
		int pos = header.find("Content-Length:");
		if(pos > 0)
		{
			INT32 endpos = header.find("\r\n", pos);
			INT32 phrlen = endpos - pos;
			std::string contlen = header.substr(pos, phrlen);
			pos = contlen.find_first_of(':');
			std::string temp = contlen.substr(pos + 1, phrlen - pos - 1);
			bodylen = atoi(temp.c_str());
		}
		else
		{
			return 0;
		}
		if(headlen > 0)
		{
			total_len = headlen  + bodylen+sizeof("\r\n\r\n")-1;
		}
		else
		{
			return 0;
		}
	}
	else
	{
		return 0;
	}
	
	

	if(WebInfo.find("POST") == std::string::npos)
	{
		body = "";

		return 0;
	}

	if(read_len < total_len)
	{
		char* buf = (char*)calloc(1, total_len-read_len);
		int len = st_read_fully(fd, buf,total_len-read_len, -1);
		read_len += len;
		WebInfo.append(buf);
		free(buf);
	}
	body = WebInfo.substr(body_pos+sizeof("\r\n\r\n")-1);
	return read_len;
}
Ejemplo n.º 25
0
hoxResult
hoxSocketAPI::read_line( st_netfd_t   fd,
                         std::string& outLine,
                         const int    timeout )
{
    const char* FNAME = "hoxSocketAPI::read_line";
    hoxResult  result = hoxRC_ERR;
    char       c;
    ssize_t    nread;
    st_utime_t timeout_usecs;

    outLine.clear();

    timeout_usecs = SEC2USEC( timeout ); // convert seconds -> microseconds

    /* Read until one of the following conditions is met:
     *  (1) One while line is read.
     *  (2) Timeout occurs.
     *  (3) An error occurs.
     */

    for ( ;; )
    {
        /* Read one character at a time */
        nread = st_read(fd, &c, 1, timeout_usecs);

        /* CASE 1: Network connection is closed */
        if ( nread == 0 )
        {
            hoxLog(LOG_INFO, "%s: Network connection closed.", FNAME);
            result = hoxRC_OK;
            break;
        }

        /* CASE 2: Possible error */
        if ( nread < 0 )
        {
            if ( errno == EINTR )  // The current thread was interrupted
            {
                continue;
            }
            else if ( errno == ETIME	) // The timeout occurred and no data was read
            {
                hoxLog(LOG_INFO, "%s: Timeout [%d secs] occurred.", FNAME, timeout);
                result = hoxRC_TIMEOUT;
                break;
            }
            else
            {
                hoxLog(LOG_SYS_WARN, "%s: Socket error.", FNAME);
                result = hoxRC_ERR;
                break;
            }
        }

        /* CASE 3: Read data OK */
        if ( c == '\n' )
        {
            result = hoxRC_OK;
            break; // Success.
        }
        else
        {
            outLine += c;

            // Impose some limit.
            if ( outLine.size() >= hoxNETWORK_MAX_MSG_SIZE )
            {
                hoxLog(LOG_WARN, "%s: Maximum message's size [%d] reached.",
                    FNAME, hoxNETWORK_MAX_MSG_SIZE );
                hoxLog(LOG_WARN, "%s: Partial read message (64 bytes) = [%s ...].",
                    FNAME, outLine.substr( 0, 64 ).c_str() );
                result = hoxRC_ERR;
                break;
            }
        }
    }

    return result;
}
Ejemplo n.º 26
0
void *_handle_peer_interconnect(void *arg) {
  assert(arg != NULL);

  LOG("[%d] 收到 rpc 客户端连接\n", self_index);

  st_netfd_t client = (st_netfd_t)arg;
  arg = NULL;

  // 握手
  // rpc客户端连入后,会主动发来客户端自己的 index
  // 长度为 1 字节
  char    buf[4096];
  ssize_t  len;

  // 先只读取 1 字节的客户端握手头,表示客户端自己的 index
  if ((len = st_read(client, buf, 1, ST_UTIME_NO_TIMEOUT)) < 0) {
    ERR("[%d] failed to handshake from client #%d: %s\n", self_index, *buf, strerror(errno));
    goto close_fd_and_quit;
  } else if (len == 0) {
    goto close_fd_and_quit;
  }

  uint8_t   client_index = (uint8_t)buf[0];

  LOG("[%d] 来自 rpc 客户端 #%d 的握手已经成功建立\n", self_index, client_index);

  // 如果 client_index 等于自己的 self_index,则这个有问题
  if (client_index == self_index) {
    ERR("[%d] rpc client promet the same index with mine.\n", self_index);
    goto close_fd_and_quit;
  }

  // 将客户端 fd 放入属于它 index 的 fd_list 内
  // 在前面的 make link to peers 当中,已经把写去远程结点的 st_netfd_t 保存于 fd_list 之内了
  // 所以不需要需要将远程连入的 st_netfd_t 保存在自己的 fd_list
  /*if (fd_list[client_index] != NULL) {
    ERR("[%d] This client #%d has connected before, replace it.\n", self_index, client_index);
    st_netfd_close(fd_list[client_index]);
  }
  fd_list[client_index] = client;*/

  // 初始化用于读取流的包结构
  struct rpc_package *package;
  package = (struct rpc_package*)calloc(1, sizeof(struct rpc_package));
  //

  const size_t pkghead_len = sizeof(rpcpkg_len);
  size_t      receive;
  size_t      cursor; // 记录数据偏移到了 buf 的什么位置

  // 循环服务处理
  for (;;) {
    if ((len = st_read(client, buf, sizeof(buf), ST_UTIME_NO_TIMEOUT)) < 0) {
      ERR("[%d] failed when read from client #%d.\n", self_index, client_index);
      goto free_package_close_fd_and_quit;
    } else if (len == 0) {
      goto free_package_close_fd_and_quit;
    } else {
      if (len > sizeof(buf))
        LOG("[%d] read %ld bytes into buffer with size: %lu bytes.\n", self_index, len, sizeof(buf));

      // 流进来数据了
      cursor = 0;
      while (cursor < len) { // 如果缓冲区内数据没有处理完

        // 如果之前没切过包,或者前一包已经完成
        if (package->total == package->received) {
          package->total = NTOH(*(rpcpkg_len *)(buf + cursor));

          if (len - cursor - pkghead_len >= package->total) {
            package->received = package->total;
          } else {
            package->received = len - cursor - pkghead_len;
          }

          memcpy(&package->data, buf + cursor + pkghead_len, package->received);

          cursor += package->received + pkghead_len;
        } else {
          // 现在处理的是断开包
          assert(package->received < package->total);

          receive = (len >= package->total - package->received) ? package->total - package->received : len;

          memcpy(&package->data + package->received, buf + cursor, receive);

          package->received += receive;
          cursor += receive;
        }

        // 如果刚刚处理过的包已经是完整包,则处决它
        if (package->received == package->total) {
          struct rpc_package_head *head = protocol_decode(package);

          switch (head->type) {
            case UNKNOW:
              break;

            case REQUEST:
              LOG("[%d] receive an rpc request with method: %s and parameter: %s\n", self_index, head->body->request.method, head->body->request.parameter);

              queue_put(queue, head);

              break;

            case RESPONSE:
              LOG("[%d] response an rpc request with result: %s\n", self_index, head->body->response.result);

              // TODO: 对 response 对象的后续处理
              protocol_package_free(head);
              head = NULL;

              break;
          }
        }
      }
    }
  }

free_package_close_fd_and_quit:
  free(package);
close_fd_and_quit:
  st_netfd_close(client);
  return 0;
}