static void _st_netfd_free_aux_data(_st_netfd_t *fd) { _st_netfd_t **p = (_st_netfd_t **) fd->aux_data; st_netfd_close(p[0]); st_netfd_close(p[1]); free(p); fd->aux_data = NULL; }
void *probe(void *data) { int sock; struct sockaddr_in rmt; st_netfd_t rmt_nfd; struct probedef *probe = (struct probedef *)data; st_utime_t start; ST_INITIATE(probe->port); 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; err_close: st_netfd_close(rmt_nfd); probe->total = ((float) (st_utime() - start)) * 0.000001; done: thread_count--; return NULL; }
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 _peer_connect(const peer_index_t index) { int client_fd, rv, result; struct addrinfo hints, *ai, *p; struct peer_info *peer_info; result = 0; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; peer_info = &peer_list[index]; LOG("[%d] 向 Peer #%d %s:%s 建立互联\n", self_index, index, peer_info->host, peer_info->port); if ((rv = getaddrinfo(peer_info->host, peer_info->port, &hints, &ai)) != 0) { ERR("[%d] failed to getaddrinfo to peer #%d\n", self_index, index); return -1; } for (p = ai; p != NULL; p = p->ai_next) { if ((client_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { continue; } if ((peer_info->rpc_fd = st_netfd_open_socket(client_fd)) == NULL) { close(client_fd); continue; } if ((rv = st_connect(peer_info->rpc_fd, p->ai_addr, p->ai_addrlen, ST_UTIME_NO_TIMEOUT)) != 0) { st_netfd_close(peer_info->rpc_fd); continue; } // 写入 1 字节的 rpc 握手头 if ((rv = st_write(peer_info->rpc_fd, (char *)&self_index, 1, ST_UTIME_NO_TIMEOUT)) == -1) { ERR("[%d] handshake failed.\n", self_index); result = -1; } break; } if (p == NULL) { ERR("[%d] failed to connect to peer #%d.\n", self_index, index); result = -1; } freeaddrinfo(ai); ai = NULL; p = NULL; return result; }
void srs_close_stfd(st_netfd_t& stfd) { if (stfd) { int fd = st_netfd_fileno(stfd); st_netfd_close(stfd); stfd = NULL; // st does not close it sometimes, // close it manually. close(fd); } }
/** * 接收 rpc 连接 * 进程的主线程在这里回环 */ void accept_client(void) { st_netfd_t client; struct sockaddr from; int fromlen = sizeof(from); while ((client = st_accept(rpc_fd, &from, &fromlen, ST_UTIME_NO_TIMEOUT)) != NULL) { st_netfd_setspecific(client, get_in_addr(&from), NULL); if (st_thread_create(handle_clientconn, &client, 0, 0) == NULL) fprintf(stderr, "[%d] failed to create the client thread: %s\n", my_index, strerror(errno)); } st_netfd_close(rpc_fd); }
/*--------------------------------------------------------------------------- * *--------------------------------------------------------------------------*/ int close_scsi_disk(void) { #ifdef DIXTRAC_LINUX_SG #ifdef STATE_THREADS return(st_netfd_close(scsidev_fd)); #else return(close(scsidev_fd)); #endif #endif #ifdef DIXTRAC_FREEBSD_CAM return 0; #endif }
void srs_close_stfd(st_netfd_t& stfd) { if (stfd) { int fd = st_netfd_fileno(stfd); st_netfd_close(stfd); stfd = NULL; // st does not close it sometimes, // close it manually. #ifndef WIN32 close(fd); #else closesocket(fd); #endif } }
static void *handle_connections(void *arg) { st_netfd_t srv_nfd, cli_nfd; struct sockaddr_in from; int fromlen; long i = (long) arg; srv_nfd = srv_socket[i].nfd; fromlen = sizeof(from); while (WAIT_THREADS(i) <= max_wait_threads) { cli_nfd = st_accept(srv_nfd, (struct sockaddr *)&from, &fromlen, ST_UTIME_NO_TIMEOUT); if (cli_nfd == NULL) { err_sys_report(errfd, "ERROR: can't accept connection: st_accept"); continue; } /* Save peer address, so we can retrieve it later */ st_netfd_setspecific(cli_nfd, &from.sin_addr, NULL); WAIT_THREADS(i)--; BUSY_THREADS(i)++; if (WAIT_THREADS(i) < min_wait_threads && TOTAL_THREADS(i) < max_threads) { /* Create another spare thread */ if (st_thread_create(handle_connections, (void *)i, 0, 0) != NULL) WAIT_THREADS(i)++; else err_sys_report(errfd, "ERROR: process %d (pid %d): can't create" " thread", my_index, my_pid); } handle_session(i, cli_nfd); st_netfd_close(cli_nfd); WAIT_THREADS(i)++; BUSY_THREADS(i)--; } WAIT_THREADS(i)--; return NULL; }
void _peer_accept(void) { st_netfd_t client; struct sockaddr from; int fromlen = sizeof(from); struct peer_info *peer_info; peer_info = &peer_list[self_index]; // 每个 Peer 的主回环 while ((client = st_accept(peer_info->rpc_fd, &from, &fromlen, ST_UTIME_NO_TIMEOUT)) != NULL) { LOG("[%d] 收到一个 RPC 互联请求\n", self_index); st_netfd_setspecific(client, get_in_addr(&from), NULL); if (st_thread_create(_handle_peer_interconnect, client, 0, 0) == NULL) ERR("[%d] failed to create the client thread: %s\n", self_index, strerror(errno)); } LOG("[%d] 完成了当前 Peer 的主循环: %s\n", self_index, strerror(errno)); st_netfd_close(peer_info->rpc_fd); }
hoxResult hoxDbClient::deinitialize() { const char* FNAME = "hoxDbClient::deinitialize"; hoxLog(LOG_DEBUG, "%s: ENTER.", FNAME); if ( ! s_bInitialized ) { hoxLog(LOG_WARN, "%s: The module has NOT YET initialized.", FNAME); return hoxRC_ERR; } /* Close the "shared" client socket. */ st_netfd_close( s_nfd ); s_nfd = NULL; s_bInitialized = false; hoxLog(LOG_DEBUG, "%s: END. (OK)", FNAME); return hoxRC_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; }
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; }
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; }
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; }
~socket_fd() { assert(_fd); assert(st_netfd_close(_fd) != -1); }
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 *push(void *data) { int sock; struct hostent *hp; struct sockaddr_in server; st_netfd_t rmt_nfd; struct thr_data *td = (struct thr_data *)data; struct q_info *q = td->q; if (HAVE_OPT(DIALSCRIPT) && !online) { int status; status = system(OPT_ARG(DIALSCRIPT)); if (WIFEXITED(status)) { if (WEXITSTATUS(status) != 0) { LOG(LOG_WARNING, "%s: error %d", OPT_ARG(DIALSCRIPT), WEXITSTATUS(status)); goto quit; } } else { LOG(LOG_ERR, "%s exited abnormally", OPT_ARG(DIALSCRIPT)); goto quit; } online = TRUE; } if ((hp = gethostbyname(q->host)) == (struct hostent *) 0) { LOG(LOG_ERR, "can't resolve %s: %s", q->host, strerror(h_errno)); q->fatal = 1; goto quit; } memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; memcpy((char *) &server.sin_addr, (char *) hp->h_addr, hp->h_length); server.sin_port = htons(q->port); sock = socket( AF_INET, SOCK_STREAM, 0 ); if (sock == -1) { LOG(LOG_ERR, "socket: %m"); q->fatal = 1; goto quit; } uw_setproctitle("connecting to %s:%d", q->host, q->port); #ifdef USE_ST if ((rmt_nfd = st_netfd_open_socket(sock)) == NULL) { LOG(LOG_ERR, "st_netfd_open_socket: %m", strerror(errno)); close(sock); q->fatal = 1; goto quit; } if (st_connect(rmt_nfd, (struct sockaddr *)&server, sizeof(server), TIMEOUT) < 0) { LOG(LOG_ERR, "%s:%d: %m", q->host, q->port, strerror(errno)); st_netfd_close(rmt_nfd); q->fatal = 1; goto quit; } #else rmt_nfd = sock; if (connect(rmt_nfd, (struct sockaddr *)&server, sizeof(server)) < 0) { LOG(LOG_ERR, "%s:%d: %m", q->host, q->port, strerror(errno)); close(rmt_nfd); q->fatal = 1; goto quit; } #endif if (pushto(rmt_nfd, td)) { LOG(LOG_INFO, "uploaded %s", td->filename); unlink(td->filename); } #ifdef USE_ST st_netfd_close(rmt_nfd); #else close(rmt_nfd); #endif quit: free(td->filename); free(td); #ifdef USE_ST q->thread_count--; thread_count--; #endif return NULL; }
static void *link_to_peers(void *arg) { int client_fd, index, rv; st_netfd_t client; struct addrinfo hints, *ai, *p; const char *host = "0.0.0.0"; fprintf(stderr, "link to perrs\n"); for (int i=0; i<vp_count; i++) { if (i == my_index) continue; char port[16]; //snprintf(port, 16 - 1, "%d", RPC_PORT + i); index = RPC_PORT + i; sprintf(port, "%d", index); memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if ((rv = getaddrinfo(host, port, &hints, &ai)) != 0) { fprintf(stderr, "[%d] failed to getaddrinfo to peer #%d\n", my_index, i); continue; } for (p = ai; p != NULL; p = p->ai_next) { if ((client_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { continue; } if ((client = st_netfd_open(client_fd)) == NULL) { close(client_fd); continue; } if ((rv = st_connect(client, p->ai_addr, p->ai_addrlen, ST_UTIME_NO_TIMEOUT)) != 0) { st_netfd_close(client); close(client_fd); continue; } else { fd_list[i] = client; } // 写入 1 字节的 rpc 握手头 if ((rv = st_write(client, (char *)&my_index, 1, ST_UTIME_NO_TIMEOUT)) == -1) { fprintf(stderr, "[%d] handshake failed.\n", my_index); } fd_list[i] = client; break; } if (p == NULL) { fprintf(stderr, "[%d] failed to connect to peer #%d.\n", my_index, i); } freeaddrinfo(ai); ai = NULL; p = NULL; // 模拟:发出第一个 rpc 包 char message[] = "hello rpc."; rpcpkg_len len = strlen(message); rpcpkg_len nlen = HTON(len); // network order of len char *package = (char*)calloc(sizeof(rpcpkg_len) + len, sizeof(char)); memcpy(package, &nlen, sizeof(len)); memcpy(package + sizeof(len), message, len); fprintf(stdout, "[%d] construction an package: << ", my_index); for (int j=0; j<len + sizeof(len); j++) { fprintf(stdout, "%02X ", *((uint8_t*)package + j)); } fprintf(stdout, " >>\n"); if ((rv = st_write(client, package, len + sizeof(rpcpkg_len), ST_UTIME_NO_TIMEOUT)) == -1) { fprintf(stderr, "[%d] failed to write package into client\n", my_index); } free(package); } return NULL; }
hoxResult hoxSocketAPI::tcp_connect( const std::string& sHost, const unsigned short int nPort, st_netfd_t& nfd ) { int iResult = 0; struct sockaddr_in serverAddress; struct hostent* hostInfo; int sock = -1; nfd = NULL; // Default: invalid socket // gethostbyname() takes a host name or ip address in "numbers and // dots" notation, and returns a pointer to a hostent structure, // which we'll need later. It's not important for us what this // structure is actually composed of. hostInfo = gethostbyname( sHost.c_str() ); if (hostInfo == NULL) { hoxLog(LOG_SYS_WARN, "%s: problem interpreting host: %s", __FUNCTION__, sHost.c_str()); return hoxRC_ERR; } // Create a socket. "AF_INET" means it will use the IPv4 protocol. // "SOCK_STREAM" means it will be a reliable connection (i.e., TCP; // for UDP use SOCK_DGRAM), and I'm not sure what the 0 for the last // parameter means, but it seems to work. sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { hoxLog(LOG_SYS_WARN, "%s: cannot create socket", __FUNCTION__); return hoxRC_ERR; } if ((nfd = st_netfd_open_socket(sock)) == NULL) { hoxLog(LOG_SYS_WARN, "%s: st_netfd_open_socket failed", __FUNCTION__); close(sock); return hoxRC_ERR; } // Connect to server. First we have to set some fields in the // serverAddress structure. The system will assign me an arbitrary // local port that is not in use. serverAddress.sin_family = hostInfo->h_addrtype; memcpy((char *) &serverAddress.sin_addr.s_addr, hostInfo->h_addr_list[0], hostInfo->h_length); serverAddress.sin_port = htons( nPort); iResult = st_connect( nfd, (struct sockaddr *) &serverAddress, sizeof(serverAddress), ST_UTIME_NO_TIMEOUT ); if ( iResult < 0 ) { hoxLog(LOG_SYS_WARN, "%s: cannot connect", __FUNCTION__); st_netfd_close( nfd ); return hoxRC_ERR; } return hoxRC_OK; }
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); }