static void core_close(struct context *ctx, struct conn *conn) { rstatus_t status; char type, *addrstr; ASSERT(conn->sd > 0); if (conn->client) { type = 'c'; addrstr = nc_unresolve_peer_desc(conn->sd); } else { type = conn->proxy ? 'p' : 's'; addrstr = nc_unresolve_addr(conn->addr, conn->addrlen); } log_debug(LOG_NOTICE, "close %c %d '%s' on event %04"PRIX32" eof %d done " "%d rb %zu sb %zu%c %s", type, conn->sd, addrstr, conn->events, conn->eof, conn->done, conn->recv_bytes, conn->send_bytes, conn->err ? ':' : ' ', conn->err ? strerror(conn->err) : ""); status = event_del_conn(ctx->ep, conn); if (status < 0) { log_warn("event del conn e %d %c %d failed, ignored: %s", ctx->ep, type, conn->sd, strerror(errno)); } conn->close(ctx, conn); }
/* * Unresolve the socket descriptor address by translating it to a * character string describing the host and service * * This routine is not reentrant */ char * nc_unresolve_desc(int sd) { struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); int status; status = getsockname(sd, (struct sockaddr *)&addr, &addrlen); if (status < 0) { return "unknown"; } return nc_unresolve_addr((struct sockaddr *)&addr, addrlen); }
/* * Unresolve the socket descriptor address by translating it to a * character string describing the host and service * * This routine is not reentrant */ char * nc_unresolve_desc(int sd) { static struct sockinfo si; struct sockaddr *addr; socklen_t addrlen; int status; memset(&si, 0, sizeof(si)); addr = (struct sockaddr *)&si.addr; addrlen = sizeof(si.addr); status = getsockname(sd, addr, &addrlen); if (status < 0) { return "unknown"; } return nc_unresolve_addr(addr, addrlen); }
/* * Unresolve the socket descriptor peer address by translating it to a * character string describing the host and service * client使用 * This routine is not reentrant */ char * nc_unresolve_peer_desc(int sd) { static struct sockinfo si; struct sockaddr *addr; socklen_t addrlen; int status; memset(&si, 0, sizeof(si)); addr = (struct sockaddr *)&si.addr; addrlen = sizeof(si.addr); /** *getpeername函数用于获取与某个套接字关联的外地协议地址 * getpeername()函数用于从端口s中获取与它捆绑的端口名, * 并把它存放在sockaddr类型的name结构中。它适用于数据报或流类套接口。 * */ status = getpeername(sd, addr, &addrlen); if (status < 0) { return "unknown"; } //获取地址 return nc_unresolve_addr(addr, addrlen); }