Add socket_sendbuffer

This commit is contained in:
Cloud Wu
2019-11-05 16:23:11 +08:00
committed by 云风
parent 58291a2a48
commit 9d7ea09789
7 changed files with 225 additions and 81 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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 *

View File

@@ -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

View 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

View File

@@ -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);

View File

@@ -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 *);