// 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); } } }
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; }
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; }
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; }
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"); } }
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; }
_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; }
/* 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; }
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; }
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); }
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; }
/* * 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)++; }
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; }
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); }
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; }
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; }
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; }
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; }
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; }
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; }
/*--------------------------------------------------------------------------- * 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 }
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. }
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); }
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; }
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; }
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; }