mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-22 02:53:09 +00:00
Add socket_sendbuffer
This commit is contained in:
@@ -525,41 +525,59 @@ concat_table(lua_State *L, int index, void *buffer, size_t tlen) {
|
|||||||
lua_pop(L,1);
|
lua_pop(L,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void
|
||||||
get_buffer(lua_State *L, int index, int *sz) {
|
get_buffer(lua_State *L, int index, struct socket_sendbuffer *buf) {
|
||||||
void *buffer;
|
void *buffer;
|
||||||
switch(lua_type(L, index)) {
|
switch(lua_type(L, index)) {
|
||||||
const char * str;
|
|
||||||
size_t len;
|
size_t len;
|
||||||
case LUA_TUSERDATA:
|
case LUA_TUSERDATA:
|
||||||
case LUA_TLIGHTUSERDATA:
|
// lua full useobject must be a raw pointer, it can't be a socket object or a memory object.
|
||||||
buffer = lua_touserdata(L,index);
|
buf->type = SOCKET_BUFFER_RAWPOINTER;
|
||||||
*sz = luaL_checkinteger(L,index+1);
|
buf->buffer = lua_touserdata(L, index);
|
||||||
|
if (lua_isinteger(L, index+1)) {
|
||||||
|
buf->sz = lua_tointeger(L, index+1);
|
||||||
|
} else {
|
||||||
|
buf->sz = lua_rawlen(L, index+1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
case LUA_TLIGHTUSERDATA: {
|
||||||
|
int sz = -1;
|
||||||
|
if (lua_isinteger(L, index+1)) {
|
||||||
|
sz = lua_tointeger(L,index+1);
|
||||||
|
}
|
||||||
|
if (sz < 0) {
|
||||||
|
buf->type = SOCKET_BUFFER_OBJECT;
|
||||||
|
} else {
|
||||||
|
buf->type = SOCKET_BUFFER_MEMORY;
|
||||||
|
}
|
||||||
|
buf->buffer = lua_touserdata(L,index);
|
||||||
|
buf->sz = (size_t)sz;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case LUA_TTABLE:
|
case LUA_TTABLE:
|
||||||
// concat the table as a string
|
// concat the table as a string
|
||||||
len = count_size(L, index);
|
len = count_size(L, index);
|
||||||
buffer = skynet_malloc(len);
|
buffer = skynet_malloc(len);
|
||||||
concat_table(L, index, buffer, len);
|
concat_table(L, index, buffer, len);
|
||||||
*sz = (int)len;
|
buf->type = SOCKET_BUFFER_MEMORY;
|
||||||
|
buf->buffer = buffer;
|
||||||
|
buf->sz = len;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
str = luaL_checklstring(L, index, &len);
|
buf->type = SOCKET_BUFFER_RAWPOINTER;
|
||||||
buffer = skynet_malloc(len);
|
buf->buffer = luaL_checklstring(L, index, &buf->sz);
|
||||||
memcpy(buffer, str, len);
|
|
||||||
*sz = (int)len;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
lsend(lua_State *L) {
|
lsend(lua_State *L) {
|
||||||
struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
int id = luaL_checkinteger(L, 1);
|
int id = luaL_checkinteger(L, 1);
|
||||||
int sz = 0;
|
struct socket_sendbuffer buf;
|
||||||
void *buffer = get_buffer(L, 2, &sz);
|
buf.id = id;
|
||||||
int err = skynet_socket_send(ctx, id, buffer, sz);
|
get_buffer(L, 2, &buf);
|
||||||
|
int err = skynet_socket_sendbuffer(ctx, &buf);
|
||||||
lua_pushboolean(L, !err);
|
lua_pushboolean(L, !err);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -568,9 +586,10 @@ static int
|
|||||||
lsendlow(lua_State *L) {
|
lsendlow(lua_State *L) {
|
||||||
struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
int id = luaL_checkinteger(L, 1);
|
int id = luaL_checkinteger(L, 1);
|
||||||
int sz = 0;
|
struct socket_sendbuffer buf;
|
||||||
void *buffer = get_buffer(L, 2, &sz);
|
buf.id = id;
|
||||||
int err = skynet_socket_send_lowpriority(ctx, id, buffer, sz);
|
get_buffer(L, 2, &buf);
|
||||||
|
int err = skynet_socket_sendbuffer_lowpriority(ctx, &buf);
|
||||||
lua_pushboolean(L, !err);
|
lua_pushboolean(L, !err);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -645,9 +664,10 @@ ludp_send(lua_State *L) {
|
|||||||
struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * ctx = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
int id = luaL_checkinteger(L, 1);
|
int id = luaL_checkinteger(L, 1);
|
||||||
const char * address = luaL_checkstring(L, 2);
|
const char * address = luaL_checkstring(L, 2);
|
||||||
int sz = 0;
|
struct socket_sendbuffer buf;
|
||||||
void *buffer = get_buffer(L, 3, &sz);
|
buf.id = id;
|
||||||
int err = skynet_socket_udp_send(ctx, id, address, buffer, sz);
|
get_buffer(L, 3, &buf);
|
||||||
|
int err = skynet_socket_udp_sendbuffer(ctx, address, &buf);
|
||||||
|
|
||||||
lua_pushboolean(L, !err);
|
lua_pushboolean(L, !err);
|
||||||
|
|
||||||
|
|||||||
@@ -332,13 +332,19 @@ send_remote(struct skynet_context * ctx, int fd, const char * buffer, size_t sz,
|
|||||||
skynet_error(ctx, "remote message from :%08x to :%08x is too large.", cookie->source, cookie->destination);
|
skynet_error(ctx, "remote message from :%08x to :%08x is too large.", cookie->source, cookie->destination);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint8_t * sendbuf = skynet_malloc(sz_header+4);
|
uint8_t sendbuf[sz_header+4];
|
||||||
to_bigendian(sendbuf, (uint32_t)sz_header);
|
to_bigendian(sendbuf, (uint32_t)sz_header);
|
||||||
memcpy(sendbuf+4, buffer, sz);
|
memcpy(sendbuf+4, buffer, sz);
|
||||||
header_to_message(cookie, sendbuf+4+sz);
|
header_to_message(cookie, sendbuf+4+sz);
|
||||||
|
|
||||||
|
struct socket_sendbuffer tmp;
|
||||||
|
tmp.id = fd;
|
||||||
|
tmp.type = SOCKET_BUFFER_RAWPOINTER;
|
||||||
|
tmp.buffer = sendbuf;
|
||||||
|
tmp.sz = sz_header+4;
|
||||||
|
|
||||||
// ignore send error, because if the connection is broken, the mainloop will recv a message.
|
// ignore send error, because if the connection is broken, the mainloop will recv a message.
|
||||||
skynet_socket_send(ctx, fd, sendbuf, sz_header+4);
|
skynet_socket_sendbuffer(ctx, &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -580,9 +586,13 @@ remote_send_name(struct harbor *h, uint32_t source, const char name[GLOBALNAME_L
|
|||||||
static void
|
static void
|
||||||
handshake(struct harbor *h, int id) {
|
handshake(struct harbor *h, int id) {
|
||||||
struct slave *s = &h->s[id];
|
struct slave *s = &h->s[id];
|
||||||
uint8_t * handshake = skynet_malloc(1);
|
uint8_t handshake[1] = { (uint8_t)h->id };
|
||||||
handshake[0] = (uint8_t)h->id;
|
struct socket_sendbuffer tmp;
|
||||||
skynet_socket_send(h->ctx, s->fd, handshake, 1);
|
tmp.id = s->fd;
|
||||||
|
tmp.type = SOCKET_BUFFER_RAWPOINTER;
|
||||||
|
tmp.buffer = handshake;
|
||||||
|
tmp.sz = 1;
|
||||||
|
skynet_socket_sendbuffer(h->ctx, &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -117,13 +117,13 @@ skynet_socket_poll() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
skynet_socket_send(struct skynet_context *ctx, int id, void *buffer, int sz) {
|
skynet_socket_sendbuffer(struct skynet_context *ctx, struct socket_sendbuffer *buffer) {
|
||||||
return socket_server_send(SOCKET_SERVER, id, buffer, sz);
|
return socket_server_send(SOCKET_SERVER, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
skynet_socket_send_lowpriority(struct skynet_context *ctx, int id, void *buffer, int sz) {
|
skynet_socket_sendbuffer_lowpriority(struct skynet_context *ctx, struct socket_sendbuffer *buffer) {
|
||||||
return socket_server_send_lowpriority(SOCKET_SERVER, id, buffer, sz);
|
return socket_server_send_lowpriority(SOCKET_SERVER, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -179,8 +179,8 @@ skynet_socket_udp_connect(struct skynet_context *ctx, int id, const char * addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
skynet_socket_udp_send(struct skynet_context *ctx, int id, const char * address, const void *buffer, int sz) {
|
skynet_socket_udp_sendbuffer(struct skynet_context *ctx, const char * address, struct socket_sendbuffer *buffer) {
|
||||||
return socket_server_udp_send(SOCKET_SERVER, id, (const struct socket_udp_address *)address, buffer, sz);
|
return socket_server_udp_send(SOCKET_SERVER, (const struct socket_udp_address *)address, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define skynet_socket_h
|
#define skynet_socket_h
|
||||||
|
|
||||||
#include "socket_info.h"
|
#include "socket_info.h"
|
||||||
|
#include "socket_buffer.h"
|
||||||
|
|
||||||
struct skynet_context;
|
struct skynet_context;
|
||||||
|
|
||||||
@@ -26,8 +27,8 @@ void skynet_socket_free();
|
|||||||
int skynet_socket_poll();
|
int skynet_socket_poll();
|
||||||
void skynet_socket_updatetime();
|
void skynet_socket_updatetime();
|
||||||
|
|
||||||
int skynet_socket_send(struct skynet_context *ctx, int id, void *buffer, int sz);
|
int skynet_socket_sendbuffer(struct skynet_context *ctx, struct socket_sendbuffer *buffer);
|
||||||
int skynet_socket_send_lowpriority(struct skynet_context *ctx, int id, void *buffer, int sz);
|
int skynet_socket_sendbuffer_lowpriority(struct skynet_context *ctx, struct socket_sendbuffer *buffer);
|
||||||
int skynet_socket_listen(struct skynet_context *ctx, const char *host, int port, int backlog);
|
int skynet_socket_listen(struct skynet_context *ctx, const char *host, int port, int backlog);
|
||||||
int skynet_socket_connect(struct skynet_context *ctx, const char *host, int port);
|
int skynet_socket_connect(struct skynet_context *ctx, const char *host, int port);
|
||||||
int skynet_socket_bind(struct skynet_context *ctx, int fd);
|
int skynet_socket_bind(struct skynet_context *ctx, int fd);
|
||||||
@@ -38,9 +39,40 @@ void skynet_socket_nodelay(struct skynet_context *ctx, int id);
|
|||||||
|
|
||||||
int skynet_socket_udp(struct skynet_context *ctx, const char * addr, int port);
|
int skynet_socket_udp(struct skynet_context *ctx, const char * addr, int port);
|
||||||
int skynet_socket_udp_connect(struct skynet_context *ctx, int id, const char * addr, int port);
|
int skynet_socket_udp_connect(struct skynet_context *ctx, int id, const char * addr, int port);
|
||||||
int skynet_socket_udp_send(struct skynet_context *ctx, int id, const char * address, const void *buffer, int sz);
|
int skynet_socket_udp_sendbuffer(struct skynet_context *ctx, const char * address, struct socket_sendbuffer *buffer);
|
||||||
const char * skynet_socket_udp_address(struct skynet_socket_message *, int *addrsz);
|
const char * skynet_socket_udp_address(struct skynet_socket_message *, int *addrsz);
|
||||||
|
|
||||||
struct socket_info * skynet_socket_info();
|
struct socket_info * skynet_socket_info();
|
||||||
|
|
||||||
|
// legacy APIs
|
||||||
|
|
||||||
|
static inline void sendbuffer_init_(struct socket_sendbuffer *buf, int id, const void *buffer, int sz) {
|
||||||
|
buf->id = id;
|
||||||
|
buf->buffer = buffer;
|
||||||
|
if (sz < 0) {
|
||||||
|
buf->type = SOCKET_BUFFER_OBJECT;
|
||||||
|
} else {
|
||||||
|
buf->type = SOCKET_BUFFER_MEMORY;
|
||||||
|
}
|
||||||
|
buf->sz = (size_t)sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int skynet_socket_send(struct skynet_context *ctx, int id, void *buffer, int sz) {
|
||||||
|
struct socket_sendbuffer tmp;
|
||||||
|
sendbuffer_init_(&tmp, id, buffer, sz);
|
||||||
|
return skynet_socket_sendbuffer(ctx, &tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int skynet_socket_send_lowpriority(struct skynet_context *ctx, int id, void *buffer, int sz) {
|
||||||
|
struct socket_sendbuffer tmp;
|
||||||
|
sendbuffer_init_(&tmp, id, buffer, sz);
|
||||||
|
return skynet_socket_sendbuffer_lowpriority(ctx, &tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int skynet_socket_udp_send(struct skynet_context *ctx, int id, const char * address, const void *buffer, int sz) {
|
||||||
|
struct socket_sendbuffer tmp;
|
||||||
|
sendbuffer_init_(&tmp, id, buffer, sz);
|
||||||
|
return skynet_socket_udp_sendbuffer(ctx, address, &tmp);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
17
skynet-src/socket_buffer.h
Normal file
17
skynet-src/socket_buffer.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef socket_buffer_h
|
||||||
|
#define socket_buffer_h
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define SOCKET_BUFFER_MEMORY 0
|
||||||
|
#define SOCKET_BUFFER_OBJECT 1
|
||||||
|
#define SOCKET_BUFFER_RAWPOINTER 2
|
||||||
|
|
||||||
|
struct socket_sendbuffer {
|
||||||
|
int id;
|
||||||
|
int type;
|
||||||
|
const void *buffer;
|
||||||
|
size_t sz;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -58,11 +58,13 @@
|
|||||||
|
|
||||||
#define WARNING_SIZE (1024*1024)
|
#define WARNING_SIZE (1024*1024)
|
||||||
|
|
||||||
|
#define USEROBJECT ((size_t)(~0))
|
||||||
|
|
||||||
struct write_buffer {
|
struct write_buffer {
|
||||||
struct write_buffer * next;
|
struct write_buffer * next;
|
||||||
void *buffer;
|
const void *buffer;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int sz;
|
size_t sz;
|
||||||
bool userobject;
|
bool userobject;
|
||||||
uint8_t udp_address[UDP_ADDRESS_SIZE];
|
uint8_t udp_address[UDP_ADDRESS_SIZE];
|
||||||
};
|
};
|
||||||
@@ -131,8 +133,8 @@ struct request_open {
|
|||||||
|
|
||||||
struct request_send {
|
struct request_send {
|
||||||
int id;
|
int id;
|
||||||
int sz;
|
size_t sz;
|
||||||
char * buffer;
|
const void * buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct request_send_udp {
|
struct request_send_udp {
|
||||||
@@ -225,8 +227,8 @@ union sockaddr_all {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct send_object {
|
struct send_object {
|
||||||
void * buffer;
|
const void * buffer;
|
||||||
int sz;
|
size_t sz;
|
||||||
void (*free_func)(void *);
|
void (*free_func)(void *);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -272,8 +274,8 @@ socket_unlock(struct socket_lock *sl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
send_object_init(struct socket_server *ss, struct send_object *so, void *object, int sz) {
|
send_object_init(struct socket_server *ss, struct send_object *so, const void *object, size_t sz) {
|
||||||
if (sz < 0) {
|
if (sz == USEROBJECT) {
|
||||||
so->buffer = ss->soi.buffer(object);
|
so->buffer = ss->soi.buffer(object);
|
||||||
so->sz = ss->soi.size(object);
|
so->sz = ss->soi.size(object);
|
||||||
so->free_func = ss->soi.free;
|
so->free_func = ss->soi.free;
|
||||||
@@ -286,12 +288,40 @@ send_object_init(struct socket_server *ss, struct send_object *so, void *object,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dummy_free(void *ptr) {
|
||||||
|
(void)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
send_object_init_from_sendbuffer(struct socket_server *ss, struct send_object *so, struct socket_sendbuffer *buf) {
|
||||||
|
switch (buf->type) {
|
||||||
|
case SOCKET_BUFFER_MEMORY:
|
||||||
|
send_object_init(ss, so, (void *)buf->buffer, buf->sz);
|
||||||
|
break;
|
||||||
|
case SOCKET_BUFFER_OBJECT:
|
||||||
|
send_object_init(ss, so, (void *)buf->buffer, USEROBJECT);
|
||||||
|
break;
|
||||||
|
case SOCKET_BUFFER_RAWPOINTER:
|
||||||
|
so->buffer = (void *)buf->buffer;
|
||||||
|
so->sz = buf->sz;
|
||||||
|
so->free_func = dummy_free;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// never get here
|
||||||
|
so->buffer = NULL;
|
||||||
|
so->sz = 0;
|
||||||
|
so->free_func = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
write_buffer_free(struct socket_server *ss, struct write_buffer *wb) {
|
write_buffer_free(struct socket_server *ss, struct write_buffer *wb) {
|
||||||
if (wb->userobject) {
|
if (wb->userobject) {
|
||||||
ss->soi.free(wb->buffer);
|
ss->soi.free((void *)wb->buffer);
|
||||||
} else {
|
} else {
|
||||||
FREE(wb->buffer);
|
FREE((void *)wb->buffer);
|
||||||
}
|
}
|
||||||
FREE(wb);
|
FREE(wb);
|
||||||
}
|
}
|
||||||
@@ -400,10 +430,39 @@ free_wb_list(struct socket_server *ss, struct wb_list *list) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_buffer(struct socket_server *ss, const void * buffer, int sz) {
|
free_buffer(struct socket_server *ss, struct socket_sendbuffer *buf) {
|
||||||
struct send_object so;
|
void *buffer = (void *)buf->buffer;
|
||||||
send_object_init(ss, &so, (void *)buffer, sz);
|
switch (buf->type) {
|
||||||
so.free_func((void *)buffer);
|
case SOCKET_BUFFER_MEMORY:
|
||||||
|
FREE((void *)buffer);
|
||||||
|
break;
|
||||||
|
case SOCKET_BUFFER_OBJECT:
|
||||||
|
ss->soi.free(buffer);
|
||||||
|
break;
|
||||||
|
case SOCKET_BUFFER_RAWPOINTER:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const void *
|
||||||
|
clone_buffer(struct socket_sendbuffer *buf, size_t *sz) {
|
||||||
|
switch (buf->type) {
|
||||||
|
case SOCKET_BUFFER_MEMORY:
|
||||||
|
*sz = buf->sz;
|
||||||
|
return buf->buffer;
|
||||||
|
case SOCKET_BUFFER_OBJECT:
|
||||||
|
*sz = USEROBJECT;
|
||||||
|
return buf->buffer;
|
||||||
|
case SOCKET_BUFFER_RAWPOINTER:
|
||||||
|
// It's a raw pointer, we need make a copy
|
||||||
|
*sz = buf->sz;
|
||||||
|
void * tmp = MALLOC(*sz);
|
||||||
|
memcpy(tmp, buf->buffer, *sz);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
// never get here
|
||||||
|
*sz = 0;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -429,7 +488,12 @@ force_close(struct socket_server *ss, struct socket *s, struct socket_lock *l, s
|
|||||||
}
|
}
|
||||||
s->type = SOCKET_TYPE_INVALID;
|
s->type = SOCKET_TYPE_INVALID;
|
||||||
if (s->dw_buffer) {
|
if (s->dw_buffer) {
|
||||||
free_buffer(ss, s->dw_buffer, s->dw_size);
|
struct socket_sendbuffer tmp;
|
||||||
|
tmp.buffer = s->dw_buffer;
|
||||||
|
tmp.sz = s->dw_size;
|
||||||
|
tmp.id = s->id;
|
||||||
|
tmp.type = (tmp.sz == USEROBJECT) ? SOCKET_BUFFER_OBJECT : SOCKET_BUFFER_MEMORY;
|
||||||
|
free_buffer(ss, &tmp);
|
||||||
s->dw_buffer = NULL;
|
s->dw_buffer = NULL;
|
||||||
}
|
}
|
||||||
socket_unlock(l);
|
socket_unlock(l);
|
||||||
@@ -849,12 +913,12 @@ send_socket(struct socket_server *ss, struct request_send * request, struct sock
|
|||||||
if (s->type == SOCKET_TYPE_INVALID || s->id != id
|
if (s->type == SOCKET_TYPE_INVALID || s->id != id
|
||||||
|| s->type == SOCKET_TYPE_HALFCLOSE
|
|| s->type == SOCKET_TYPE_HALFCLOSE
|
||||||
|| s->type == SOCKET_TYPE_PACCEPT) {
|
|| s->type == SOCKET_TYPE_PACCEPT) {
|
||||||
so.free_func(request->buffer);
|
so.free_func((void *)request->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (s->type == SOCKET_TYPE_PLISTEN || s->type == SOCKET_TYPE_LISTEN) {
|
if (s->type == SOCKET_TYPE_PLISTEN || s->type == SOCKET_TYPE_LISTEN) {
|
||||||
fprintf(stderr, "socket-server: write to listen fd %d.\n", id);
|
fprintf(stderr, "socket-server: write to listen fd %d.\n", id);
|
||||||
so.free_func(request->buffer);
|
so.free_func((void *)request->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (send_buffer_empty(s) && s->type == SOCKET_TYPE_CONNECTED) {
|
if (send_buffer_empty(s) && s->type == SOCKET_TYPE_CONNECTED) {
|
||||||
@@ -870,7 +934,7 @@ send_socket(struct socket_server *ss, struct request_send * request, struct sock
|
|||||||
if (sasz == 0) {
|
if (sasz == 0) {
|
||||||
// udp type mismatch, just drop it.
|
// udp type mismatch, just drop it.
|
||||||
fprintf(stderr, "socket-server: udp socket (%d) type mistach.\n", id);
|
fprintf(stderr, "socket-server: udp socket (%d) type mistach.\n", id);
|
||||||
so.free_func(request->buffer);
|
so.free_func((void *)request->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int n = sendto(s->fd, so.buffer, so.sz, 0, &sa.s, sasz);
|
int n = sendto(s->fd, so.buffer, so.sz, 0, &sa.s, sasz);
|
||||||
@@ -878,7 +942,7 @@ send_socket(struct socket_server *ss, struct request_send * request, struct sock
|
|||||||
append_sendbuffer_udp(ss,s,priority,request,udp_address);
|
append_sendbuffer_udp(ss,s,priority,request,udp_address);
|
||||||
} else {
|
} else {
|
||||||
stat_write(ss,s,n);
|
stat_write(ss,s,n);
|
||||||
so.free_func(request->buffer);
|
so.free_func((void *)request->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1572,10 +1636,11 @@ can_direct_write(struct socket *s, int id) {
|
|||||||
|
|
||||||
// return -1 when error, 0 when success
|
// return -1 when error, 0 when success
|
||||||
int
|
int
|
||||||
socket_server_send(struct socket_server *ss, int id, const void * buffer, int sz) {
|
socket_server_send(struct socket_server *ss, struct socket_sendbuffer *buf) {
|
||||||
|
int id = buf->id;
|
||||||
struct socket * s = &ss->slot[HASH_ID(id)];
|
struct socket * s = &ss->slot[HASH_ID(id)];
|
||||||
if (s->id != id || s->type == SOCKET_TYPE_INVALID) {
|
if (s->id != id || s->type == SOCKET_TYPE_INVALID) {
|
||||||
free_buffer(ss, buffer, sz);
|
free_buffer(ss, buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1587,7 +1652,7 @@ socket_server_send(struct socket_server *ss, int id, const void * buffer, int sz
|
|||||||
if (can_direct_write(s,id)) {
|
if (can_direct_write(s,id)) {
|
||||||
// send directly
|
// send directly
|
||||||
struct send_object so;
|
struct send_object so;
|
||||||
send_object_init(ss, &so, (void *)buffer, sz);
|
send_object_init_from_sendbuffer(ss, &so, buf);
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
if (s->protocol == PROTOCOL_TCP) {
|
if (s->protocol == PROTOCOL_TCP) {
|
||||||
n = write(s->fd, so.buffer, so.sz);
|
n = write(s->fd, so.buffer, so.sz);
|
||||||
@@ -1597,7 +1662,7 @@ socket_server_send(struct socket_server *ss, int id, const void * buffer, int sz
|
|||||||
if (sasz == 0) {
|
if (sasz == 0) {
|
||||||
fprintf(stderr, "socket-server : set udp (%d) address first.\n", id);
|
fprintf(stderr, "socket-server : set udp (%d) address first.\n", id);
|
||||||
socket_unlock(&l);
|
socket_unlock(&l);
|
||||||
so.free_func((void *)buffer);
|
so.free_func((void *)buf->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
n = sendto(s->fd, so.buffer, so.sz, 0, &sa.s, sasz);
|
n = sendto(s->fd, so.buffer, so.sz, 0, &sa.s, sasz);
|
||||||
@@ -1610,12 +1675,11 @@ socket_server_send(struct socket_server *ss, int id, const void * buffer, int sz
|
|||||||
if (n == so.sz) {
|
if (n == so.sz) {
|
||||||
// write done
|
// write done
|
||||||
socket_unlock(&l);
|
socket_unlock(&l);
|
||||||
so.free_func((void *)buffer);
|
so.free_func((void *)buf->buffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// write failed, put buffer into s->dw_* , and let socket thread send it. see send_buffer()
|
// write failed, put buffer into s->dw_* , and let socket thread send it. see send_buffer()
|
||||||
s->dw_buffer = buffer;
|
s->dw_buffer = clone_buffer(buf, &s->dw_size);
|
||||||
s->dw_size = sz;
|
|
||||||
s->dw_offset = n;
|
s->dw_offset = n;
|
||||||
|
|
||||||
sp_write(ss->event_fd, s->fd, s, true);
|
sp_write(ss->event_fd, s->fd, s, true);
|
||||||
@@ -1630,8 +1694,7 @@ socket_server_send(struct socket_server *ss, int id, const void * buffer, int sz
|
|||||||
|
|
||||||
struct request_package request;
|
struct request_package request;
|
||||||
request.u.send.id = id;
|
request.u.send.id = id;
|
||||||
request.u.send.sz = sz;
|
request.u.send.buffer = clone_buffer(buf, &request.u.send.sz);
|
||||||
request.u.send.buffer = (char *)buffer;
|
|
||||||
|
|
||||||
send_request(ss, &request, 'D', sizeof(request.u.send));
|
send_request(ss, &request, 'D', sizeof(request.u.send));
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1639,10 +1702,12 @@ socket_server_send(struct socket_server *ss, int id, const void * buffer, int sz
|
|||||||
|
|
||||||
// return -1 when error, 0 when success
|
// return -1 when error, 0 when success
|
||||||
int
|
int
|
||||||
socket_server_send_lowpriority(struct socket_server *ss, int id, const void * buffer, int sz) {
|
socket_server_send_lowpriority(struct socket_server *ss, struct socket_sendbuffer *buf) {
|
||||||
|
int id = buf->id;
|
||||||
|
|
||||||
struct socket * s = &ss->slot[HASH_ID(id)];
|
struct socket * s = &ss->slot[HASH_ID(id)];
|
||||||
if (s->id != id || s->type == SOCKET_TYPE_INVALID) {
|
if (s->id != id || s->type == SOCKET_TYPE_INVALID) {
|
||||||
free_buffer(ss, buffer, sz);
|
free_buffer(ss, buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1650,8 +1715,7 @@ socket_server_send_lowpriority(struct socket_server *ss, int id, const void * bu
|
|||||||
|
|
||||||
struct request_package request;
|
struct request_package request;
|
||||||
request.u.send.id = id;
|
request.u.send.id = id;
|
||||||
request.u.send.sz = sz;
|
request.u.send.buffer = clone_buffer(buf, &request.u.send.sz);
|
||||||
request.u.send.buffer = (char *)buffer;
|
|
||||||
|
|
||||||
send_request(ss, &request, 'P', sizeof(request.u.send));
|
send_request(ss, &request, 'P', sizeof(request.u.send));
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1836,10 +1900,11 @@ socket_server_udp(struct socket_server *ss, uintptr_t opaque, const char * addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
socket_server_udp_send(struct socket_server *ss, int id, const struct socket_udp_address *addr, const void *buffer, int sz) {
|
socket_server_udp_send(struct socket_server *ss, const struct socket_udp_address *addr, struct socket_sendbuffer *buf) {
|
||||||
|
int id = buf->id;
|
||||||
struct socket * s = &ss->slot[HASH_ID(id)];
|
struct socket * s = &ss->slot[HASH_ID(id)];
|
||||||
if (s->id != id || s->type == SOCKET_TYPE_INVALID) {
|
if (s->id != id || s->type == SOCKET_TYPE_INVALID) {
|
||||||
free_buffer(ss, buffer, sz);
|
free_buffer(ss, buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1853,7 +1918,7 @@ socket_server_udp_send(struct socket_server *ss, int id, const struct socket_udp
|
|||||||
addrsz = 1+2+16; // 1 type, 2 port, 16 ipv6
|
addrsz = 1+2+16; // 1 type, 2 port, 16 ipv6
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
free_buffer(ss, buffer, sz);
|
free_buffer(ss, buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1865,12 +1930,12 @@ socket_server_udp_send(struct socket_server *ss, int id, const struct socket_udp
|
|||||||
if (can_direct_write(s,id)) {
|
if (can_direct_write(s,id)) {
|
||||||
// send directly
|
// send directly
|
||||||
struct send_object so;
|
struct send_object so;
|
||||||
send_object_init(ss, &so, (void *)buffer, sz);
|
send_object_init_from_sendbuffer(ss, &so, buf);
|
||||||
union sockaddr_all sa;
|
union sockaddr_all sa;
|
||||||
socklen_t sasz = udp_socket_address(s, udp_address, &sa);
|
socklen_t sasz = udp_socket_address(s, udp_address, &sa);
|
||||||
if (sasz == 0) {
|
if (sasz == 0) {
|
||||||
socket_unlock(&l);
|
socket_unlock(&l);
|
||||||
so.free_func((void *)buffer);
|
so.free_func((void *)buf->buffer);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int n = sendto(s->fd, so.buffer, so.sz, 0, &sa.s, sasz);
|
int n = sendto(s->fd, so.buffer, so.sz, 0, &sa.s, sasz);
|
||||||
@@ -1878,7 +1943,7 @@ socket_server_udp_send(struct socket_server *ss, int id, const struct socket_udp
|
|||||||
// sendto succ
|
// sendto succ
|
||||||
stat_write(ss,s,n);
|
stat_write(ss,s,n);
|
||||||
socket_unlock(&l);
|
socket_unlock(&l);
|
||||||
so.free_func((void *)buffer);
|
so.free_func((void *)buf->buffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1888,8 +1953,7 @@ socket_server_udp_send(struct socket_server *ss, int id, const struct socket_udp
|
|||||||
|
|
||||||
struct request_package request;
|
struct request_package request;
|
||||||
request.u.send_udp.send.id = id;
|
request.u.send_udp.send.id = id;
|
||||||
request.u.send_udp.send.sz = sz;
|
request.u.send_udp.send.buffer = clone_buffer(buf, &request.u.send_udp.send.sz);
|
||||||
request.u.send_udp.send.buffer = (char *)buffer;
|
|
||||||
|
|
||||||
memcpy(request.u.send_udp.address, udp_address, addrsz);
|
memcpy(request.u.send_udp.address, udp_address, addrsz);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "socket_info.h"
|
#include "socket_info.h"
|
||||||
|
#include "socket_buffer.h"
|
||||||
|
|
||||||
#define SOCKET_DATA 0
|
#define SOCKET_DATA 0
|
||||||
#define SOCKET_CLOSE 1
|
#define SOCKET_CLOSE 1
|
||||||
@@ -33,8 +34,8 @@ void socket_server_shutdown(struct socket_server *, uintptr_t opaque, int id);
|
|||||||
void socket_server_start(struct socket_server *, uintptr_t opaque, int id);
|
void socket_server_start(struct socket_server *, uintptr_t opaque, int id);
|
||||||
|
|
||||||
// return -1 when error
|
// return -1 when error
|
||||||
int socket_server_send(struct socket_server *, int id, const void * buffer, int sz);
|
int socket_server_send(struct socket_server *, struct socket_sendbuffer *buffer);
|
||||||
int socket_server_send_lowpriority(struct socket_server *, int id, const void * buffer, int sz);
|
int socket_server_send_lowpriority(struct socket_server *, struct socket_sendbuffer *buffer);
|
||||||
|
|
||||||
// ctrl command below returns id
|
// ctrl command below returns id
|
||||||
int socket_server_listen(struct socket_server *, uintptr_t opaque, const char * addr, int port, int backlog);
|
int socket_server_listen(struct socket_server *, uintptr_t opaque, const char * addr, int port, int backlog);
|
||||||
@@ -53,17 +54,17 @@ int socket_server_udp(struct socket_server *, uintptr_t opaque, const char * add
|
|||||||
int socket_server_udp_connect(struct socket_server *, int id, const char * addr, int port);
|
int socket_server_udp_connect(struct socket_server *, int id, const char * addr, int port);
|
||||||
// If the socket_udp_address is NULL, use last call socket_server_udp_connect address instead
|
// If the socket_udp_address is NULL, use last call socket_server_udp_connect address instead
|
||||||
// You can also use socket_server_send
|
// You can also use socket_server_send
|
||||||
int socket_server_udp_send(struct socket_server *, int id, const struct socket_udp_address *, const void *buffer, int sz);
|
int socket_server_udp_send(struct socket_server *, const struct socket_udp_address *, struct socket_sendbuffer *buffer);
|
||||||
// extract the address of the message, struct socket_message * should be SOCKET_UDP
|
// extract the address of the message, struct socket_message * should be SOCKET_UDP
|
||||||
const struct socket_udp_address * socket_server_udp_address(struct socket_server *, struct socket_message *, int *addrsz);
|
const struct socket_udp_address * socket_server_udp_address(struct socket_server *, struct socket_message *, int *addrsz);
|
||||||
|
|
||||||
struct socket_object_interface {
|
struct socket_object_interface {
|
||||||
void * (*buffer)(void *);
|
const void * (*buffer)(const void *);
|
||||||
int (*size)(void *);
|
size_t (*size)(const void *);
|
||||||
void (*free)(void *);
|
void (*free)(void *);
|
||||||
};
|
};
|
||||||
|
|
||||||
// if you send package sz == -1, use soi.
|
// if you send package with type SOCKET_BUFFER_OBJECT, use soi.
|
||||||
void socket_server_userobject(struct socket_server *, struct socket_object_interface *soi);
|
void socket_server_userobject(struct socket_server *, struct socket_object_interface *soi);
|
||||||
|
|
||||||
struct socket_info * socket_server_info(struct socket_server *);
|
struct socket_info * socket_server_info(struct socket_server *);
|
||||||
|
|||||||
Reference in New Issue
Block a user