mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 12:20:41 +00:00
add socket.netstat
This commit is contained in:
@@ -15,7 +15,7 @@ static struct socket_server * SOCKET_SERVER = NULL;
|
||||
|
||||
void
|
||||
skynet_socket_init() {
|
||||
SOCKET_SERVER = socket_server_create();
|
||||
SOCKET_SERVER = socket_server_create(skynet_now());
|
||||
}
|
||||
|
||||
void
|
||||
@@ -29,6 +29,11 @@ skynet_socket_free() {
|
||||
SOCKET_SERVER = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
skynet_socket_updatetime() {
|
||||
socket_server_updatetime(SOCKET_SERVER, skynet_now());
|
||||
}
|
||||
|
||||
// mainloop thread
|
||||
static void
|
||||
forward_message(int type, bool padding, struct socket_message * result) {
|
||||
@@ -190,3 +195,8 @@ skynet_socket_udp_address(struct skynet_socket_message *msg, int *addrsz) {
|
||||
sm.data = msg->buffer;
|
||||
return (const char *)socket_server_udp_address(SOCKET_SERVER, &sm, addrsz);
|
||||
}
|
||||
|
||||
struct socket_info *
|
||||
skynet_socket_info() {
|
||||
return socket_server_info(SOCKET_SERVER);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef skynet_socket_h
|
||||
#define skynet_socket_h
|
||||
|
||||
#include "socket_info.h"
|
||||
|
||||
struct skynet_context;
|
||||
|
||||
#define SKYNET_SOCKET_TYPE_DATA 1
|
||||
@@ -22,6 +24,7 @@ void skynet_socket_init();
|
||||
void skynet_socket_exit();
|
||||
void skynet_socket_free();
|
||||
int skynet_socket_poll();
|
||||
void skynet_socket_updatetime();
|
||||
|
||||
int skynet_socket_send(struct skynet_context *ctx, int id, void *buffer, int sz);
|
||||
int skynet_socket_send_lowpriority(struct skynet_context *ctx, int id, void *buffer, int sz);
|
||||
@@ -38,4 +41,6 @@ int skynet_socket_udp_connect(struct skynet_context *ctx, int id, const char * a
|
||||
int skynet_socket_udp_send(struct skynet_context *ctx, int id, const char * address, const void *buffer, int sz);
|
||||
const char * skynet_socket_udp_address(struct skynet_socket_message *, int *addrsz);
|
||||
|
||||
struct socket_info * skynet_socket_info();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -131,6 +131,7 @@ thread_timer(void *p) {
|
||||
skynet_initthread(THREAD_TIMER);
|
||||
for (;;) {
|
||||
skynet_updatetime();
|
||||
skynet_socket_updatetime();
|
||||
CHECK_ABORT
|
||||
wakeup(m,m->count-1);
|
||||
usleep(2500);
|
||||
|
||||
28
skynet-src/socket_info.h
Normal file
28
skynet-src/socket_info.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef socket_info_h
|
||||
#define socket_info_h
|
||||
|
||||
#define SOCKET_INFO_UNKNOWN 0
|
||||
#define SOCKET_INFO_LISTEN 1
|
||||
#define SOCKET_INFO_TCP 2
|
||||
#define SOCKET_INFO_UDP 3
|
||||
#define SOCKET_INFO_BIND 4
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct socket_info {
|
||||
int id;
|
||||
int type;
|
||||
uint64_t opaque;
|
||||
uint64_t read;
|
||||
uint64_t write;
|
||||
uint64_t rtime;
|
||||
uint64_t wtime;
|
||||
int64_t wbuffer;
|
||||
char name[128];
|
||||
struct socket_info *next;
|
||||
};
|
||||
|
||||
struct socket_info * socket_info_create(struct socket_info *last);
|
||||
void socket_info_release(struct socket_info *);
|
||||
|
||||
#endif
|
||||
@@ -75,11 +75,19 @@ struct wb_list {
|
||||
struct write_buffer * tail;
|
||||
};
|
||||
|
||||
struct socket_stat {
|
||||
uint64_t rtime;
|
||||
uint64_t wtime;
|
||||
uint64_t read;
|
||||
uint64_t write;
|
||||
};
|
||||
|
||||
struct socket {
|
||||
uintptr_t opaque;
|
||||
struct wb_list high;
|
||||
struct wb_list low;
|
||||
int64_t wb_size;
|
||||
struct socket_stat stat;
|
||||
volatile uint32_t sending;
|
||||
int fd;
|
||||
int id;
|
||||
@@ -98,6 +106,7 @@ struct socket {
|
||||
};
|
||||
|
||||
struct socket_server {
|
||||
volatile uint64_t time;
|
||||
int recvctrl_fd;
|
||||
int sendctrl_fd;
|
||||
int checkctrl;
|
||||
@@ -188,6 +197,7 @@ struct request_udp {
|
||||
T Set opt
|
||||
U Create UDP socket
|
||||
C set udp address
|
||||
Q query info
|
||||
*/
|
||||
|
||||
struct request_package {
|
||||
@@ -326,7 +336,7 @@ clear_wb_list(struct wb_list *list) {
|
||||
}
|
||||
|
||||
struct socket_server *
|
||||
socket_server_create() {
|
||||
socket_server_create(uint64_t time) {
|
||||
int i;
|
||||
int fd[2];
|
||||
poll_fd efd = sp_create();
|
||||
@@ -349,6 +359,7 @@ socket_server_create() {
|
||||
}
|
||||
|
||||
struct socket_server *ss = MALLOC(sizeof(*ss));
|
||||
ss->time = time;
|
||||
ss->event_fd = efd;
|
||||
ss->recvctrl_fd = fd[0];
|
||||
ss->sendctrl_fd = fd[1];
|
||||
@@ -371,6 +382,11 @@ socket_server_create() {
|
||||
return ss;
|
||||
}
|
||||
|
||||
void
|
||||
socket_server_updatetime(struct socket_server *ss, uint64_t time) {
|
||||
ss->time = time;
|
||||
}
|
||||
|
||||
static void
|
||||
free_wb_list(struct socket_server *ss, struct wb_list *list) {
|
||||
struct write_buffer *wb = list->head;
|
||||
@@ -468,9 +484,22 @@ new_fd(struct socket_server *ss, int id, int fd, int protocol, uintptr_t opaque,
|
||||
check_wb_list(&s->low);
|
||||
s->dw_buffer = NULL;
|
||||
s->dw_size = 0;
|
||||
memset(&s->stat, 0, sizeof(s->stat));
|
||||
return s;
|
||||
}
|
||||
|
||||
static inline void
|
||||
stat_read(struct socket_server *ss, struct socket *s, int n) {
|
||||
s->stat.read += n;
|
||||
s->stat.rtime = ss->time;
|
||||
}
|
||||
|
||||
static inline void
|
||||
stat_write(struct socket_server *ss, struct socket *s, int n) {
|
||||
s->stat.write += n;
|
||||
s->stat.wtime = ss->time;
|
||||
}
|
||||
|
||||
// return -1 when connecting
|
||||
static int
|
||||
open_socket(struct socket_server *ss, struct request_open * request, struct socket_message *result) {
|
||||
@@ -563,6 +592,7 @@ send_list_tcp(struct socket_server *ss, struct socket *s, struct wb_list *list,
|
||||
force_close(ss,s,l,result);
|
||||
return SOCKET_CLOSE;
|
||||
}
|
||||
stat_write(ss,s,(int)sz);
|
||||
s->wb_size -= sz;
|
||||
if (sz != tmp->sz) {
|
||||
tmp->ptr += sz;
|
||||
@@ -634,7 +664,7 @@ send_list_udp(struct socket_server *ss, struct socket *s, struct wb_list *list,
|
||||
drop_udp(ss, s, list, tmp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
stat_write(ss,s,tmp->sz);
|
||||
s->wb_size -= tmp->sz;
|
||||
list->head = tmp->next;
|
||||
write_buffer_free(ss,tmp);
|
||||
@@ -847,6 +877,7 @@ send_socket(struct socket_server *ss, struct request_send * request, struct sock
|
||||
if (n != so.sz) {
|
||||
append_sendbuffer_udp(ss,s,priority,request,udp_address);
|
||||
} else {
|
||||
stat_write(ss,s,n);
|
||||
so.free_func(request->buffer);
|
||||
return -1;
|
||||
}
|
||||
@@ -1193,6 +1224,8 @@ forward_message_tcp(struct socket_server *ss, struct socket *s, struct socket_lo
|
||||
return -1;
|
||||
}
|
||||
|
||||
stat_read(ss,s,n);
|
||||
|
||||
if (n == sz) {
|
||||
s->p.size *= 2;
|
||||
} else if (sz > MIN_READ_BUFFER && n*2 < sz) {
|
||||
@@ -1242,6 +1275,8 @@ forward_message_udp(struct socket_server *ss, struct socket *s, struct socket_lo
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
stat_read(ss,s,n);
|
||||
|
||||
uint8_t * data;
|
||||
if (slen == sizeof(sa.v4)) {
|
||||
if (s->protocol != PROTOCOL_UDP)
|
||||
@@ -1298,6 +1333,20 @@ report_connect(struct socket_server *ss, struct socket *s, struct socket_lock *l
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
getname(union sockaddr_all *u, char *buffer, size_t sz) {
|
||||
char tmp[INET6_ADDRSTRLEN];
|
||||
void * sin_addr = (u->s.sa_family == AF_INET) ? (void*)&u->v4.sin_addr : (void *)&u->v6.sin6_addr;
|
||||
int sin_port = ntohs((u->s.sa_family == AF_INET) ? u->v4.sin_port : u->v6.sin6_port);
|
||||
if (inet_ntop(u->s.sa_family, sin_addr, tmp, sizeof(tmp))) {
|
||||
snprintf(buffer, sz, "%s:%d", tmp, sin_port);
|
||||
return 1;
|
||||
} else {
|
||||
buffer[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// return 0 when failed, or -1 when file limit
|
||||
static int
|
||||
report_accept(struct socket_server *ss, struct socket *s, struct socket_message *result) {
|
||||
@@ -1327,17 +1376,16 @@ report_accept(struct socket_server *ss, struct socket *s, struct socket_message
|
||||
close(client_fd);
|
||||
return 0;
|
||||
}
|
||||
// accept new one connection
|
||||
stat_read(ss,s,1);
|
||||
|
||||
ns->type = SOCKET_TYPE_PACCEPT;
|
||||
result->opaque = s->opaque;
|
||||
result->id = s->id;
|
||||
result->ud = id;
|
||||
result->data = NULL;
|
||||
|
||||
void * sin_addr = (u.s.sa_family == AF_INET) ? (void*)&u.v4.sin_addr : (void *)&u.v6.sin6_addr;
|
||||
int sin_port = ntohs((u.s.sa_family == AF_INET) ? u.v4.sin_port : u.v6.sin6_port);
|
||||
char tmp[INET6_ADDRSTRLEN];
|
||||
if (inet_ntop(u.s.sa_family, sin_addr, tmp, sizeof(tmp))) {
|
||||
snprintf(ss->buffer, sizeof(ss->buffer), "%s:%d", tmp, sin_port);
|
||||
if (getname(&u, ss->buffer, sizeof(ss->buffer))) {
|
||||
result->data = ss->buffer;
|
||||
}
|
||||
|
||||
@@ -1558,6 +1606,7 @@ socket_server_send(struct socket_server *ss, int id, const void * buffer, int sz
|
||||
// ignore error, let socket thread try again
|
||||
n = 0;
|
||||
}
|
||||
stat_write(ss,s,n);
|
||||
if (n == so.sz) {
|
||||
// write done
|
||||
socket_unlock(&l);
|
||||
@@ -1827,6 +1876,7 @@ socket_server_udp_send(struct socket_server *ss, int id, const struct socket_udp
|
||||
int n = sendto(s->fd, so.buffer, so.sz, 0, &sa.s, sasz);
|
||||
if (n >= 0) {
|
||||
// sendto succ
|
||||
stat_write(ss,s,n);
|
||||
socket_unlock(&l);
|
||||
so.free_func((void *)buffer);
|
||||
return 0;
|
||||
@@ -1915,3 +1965,81 @@ socket_server_udp_address(struct socket_server *ss, struct socket_message *msg,
|
||||
}
|
||||
return (const struct socket_udp_address *)address;
|
||||
}
|
||||
|
||||
|
||||
struct socket_info *
|
||||
socket_info_create(struct socket_info *last) {
|
||||
struct socket_info *si = skynet_malloc(sizeof(*si));
|
||||
memset(si, 0 , sizeof(*si));
|
||||
si->next = last;
|
||||
return si;
|
||||
}
|
||||
|
||||
void
|
||||
socket_info_release(struct socket_info *si) {
|
||||
while (si) {
|
||||
struct socket_info *temp = si;
|
||||
si = si->next;
|
||||
skynet_free(temp);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
query_info(struct socket *s, struct socket_info *si) {
|
||||
union sockaddr_all u;
|
||||
socklen_t slen = sizeof(u);
|
||||
switch (s->type) {
|
||||
case SOCKET_TYPE_BIND:
|
||||
si->type = SOCKET_INFO_BIND;
|
||||
si->name[0] = '\0';
|
||||
break;
|
||||
case SOCKET_TYPE_LISTEN:
|
||||
si->type = SOCKET_INFO_LISTEN;
|
||||
if (getsockname(s->fd, &u.s, &slen) == 0) {
|
||||
getname(&u, si->name, sizeof(si->name));
|
||||
}
|
||||
break;
|
||||
case SOCKET_TYPE_CONNECTED:
|
||||
if (s->protocol == PROTOCOL_TCP) {
|
||||
si->type = SOCKET_INFO_TCP;
|
||||
if (getpeername(s->fd, &u.s, &slen) == 0) {
|
||||
getname(&u, si->name, sizeof(si->name));
|
||||
}
|
||||
} else {
|
||||
si->type = SOCKET_INFO_UDP;
|
||||
if (udp_socket_address(s, s->p.udp_address, &u)) {
|
||||
getname(&u, si->name, sizeof(si->name));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
si->id = s->id;
|
||||
si->opaque = (uint64_t)s->opaque;
|
||||
si->read = s->stat.read;
|
||||
si->write = s->stat.write;
|
||||
si->rtime = s->stat.rtime;
|
||||
si->wtime = s->stat.wtime;
|
||||
si->wbuffer = s->wb_size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct socket_info *
|
||||
socket_server_info(struct socket_server *ss) {
|
||||
int i;
|
||||
struct socket_info * si = NULL;
|
||||
for (i=0;i<MAX_SOCKET;i++) {
|
||||
struct socket * s = &ss->slot[i];
|
||||
int id = s->id;
|
||||
struct socket_info temp;
|
||||
if (query_info(s, &temp) && s->id == id) {
|
||||
// socket_server_info may call in different thread, so check socket id again
|
||||
si = socket_info_create(si);
|
||||
temp.next = si->next;
|
||||
*si = temp;
|
||||
}
|
||||
}
|
||||
return si;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define skynet_socket_server_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include "socket_info.h"
|
||||
|
||||
#define SOCKET_DATA 0
|
||||
#define SOCKET_CLOSE 1
|
||||
@@ -21,8 +22,9 @@ struct socket_message {
|
||||
char * data;
|
||||
};
|
||||
|
||||
struct socket_server * socket_server_create();
|
||||
struct socket_server * socket_server_create(uint64_t time);
|
||||
void socket_server_release(struct socket_server *);
|
||||
void socket_server_updatetime(struct socket_server *, uint64_t time);
|
||||
int socket_server_poll(struct socket_server *, struct socket_message *result, int *more);
|
||||
|
||||
void socket_server_exit(struct socket_server *);
|
||||
@@ -64,4 +66,6 @@ struct socket_object_interface {
|
||||
// if you send package sz == -1, use soi.
|
||||
void socket_server_userobject(struct socket_server *, struct socket_object_interface *soi);
|
||||
|
||||
struct socket_info * socket_server_info(struct socket_server *);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user