static const void* rpacket_raw_read_binary(rpacket_t r,uint32_t *len) { void *addr = 0; uint32_t size = 0; if(!r->data_remain) return addr; if(r->readbuf->size - r->rpos >= r->data_remain) { *len = r->data_remain; r->data_remain = 0; addr = &r->readbuf->buf[r->rpos]; r->rpos += r->data_remain; } else { if(!r->binbuf) { r->binbufpos = 0; r->binbuf = buffer_create_and_acquire(r->mt,NULL,r->len); } addr = r->binbuf->buf + r->binbufpos; size = r->data_remain; while(size) { uint32_t copy_size = r->readbuf->size - r->rpos; copy_size = copy_size >= size ? size:copy_size; memcpy(r->binbuf->buf + r->binbufpos,r->readbuf->buf + r->rpos,copy_size); size -= copy_size; r->rpos += copy_size; r->data_remain -= copy_size; r->binbufpos += copy_size; if(r->rpos >= r->readbuf->size && r->data_remain) { //当前buffer数据已经被读完,切换到下一个buffer r->rpos = 0; r->readbuf = buffer_acquire(r->readbuf,r->readbuf->next); } } } return addr; }
wpacket_t wpacket_create(uint8_t mt,allocator_t _allo,uint32_t size,uint8_t is_raw) { size = GetSize_of_pow2(size); wpacket_t w = (wpacket_t)ALLOC(_allo,sizeof(*w)); w->allocator = _allo; w->mt = mt; w->factor = size; w->raw = is_raw; w->buf = buffer_create_and_acquire(mt,NULL,size); w->writebuf = buffer_acquire(NULL,w->buf); w->begin_pos = 0; w->next.next = NULL; w->_packet_send_finish = NULL; w->type = MSG_WPACKET; if(is_raw) { w->wpos = 0; w->len = 0; w->buf->size = 0; w->data_size = 0; } else { w->wpos = sizeof(*(w->len)); w->len = (uint32_t*)w->buf->buf; *(w->len) = 0; w->buf->size = sizeof(*(w->len)); w->data_size = sizeof(*(w->len)); } //ATOMIC_INCREASE(&wpacket_count); return w; }
static void wpacket_expand(wpacket_t w) { uint32_t size; w->factor <<= 1; size = 1 << w->factor; w->writebuf->next = buffer_create_and_acquire(0,size); w->writebuf = buffer_acquire(w->writebuf,w->writebuf->next); w->wpos = 0; }
static inline void start_recv(struct connection *c) { if(test_recvable(c->status)){ c->unpack_buf = buffer_create_and_acquire(NULL,BUFFER_SIZE); c->next_recv_buf = buffer_acquire(NULL,c->unpack_buf); c->wrecvbuf[0].iov_len = BUFFER_SIZE; c->wrecvbuf[0].iov_base = c->next_recv_buf->buf; c->recv_overlap.m_super.iovec_count = 1; c->recv_overlap.m_super.iovec = c->wrecvbuf; c->last_recv = GetSystemMs64(); Post_Recv(c->socket,&c->recv_overlap.m_super); } }
const void* rpacket_read_binary(rpacket_t r,uint32_t *len) { void *addr = 0; uint32_t size = 0; if(r->raw) return rpacket_raw_read_binary(r,len); size = rpacket_read_uint32(r); *len = size; if(!r->data_remain || r->data_remain < size) return addr; if(r->readbuf->size - r->rpos >= size) { addr = &r->readbuf->buf[r->rpos]; r->rpos += size; r->data_remain -= size; if(r->rpos >= r->readbuf->size && r->data_remain) { //当前buffer数据已经被读完,切换到下一个buffer r->rpos = 0; r->readbuf = buffer_acquire(r->readbuf,r->readbuf->next); } } else { //数据跨越了buffer边界,创建binbuf,将数据拷贝到binbuf中 if(!r->binbuf) { r->binbufpos = 0; r->binbuf = buffer_create_and_acquire(r->mt,NULL,r->len); } addr = r->binbuf->buf + r->binbufpos; while(size) { uint32_t copy_size = r->readbuf->size - r->rpos; copy_size = copy_size >= size ? size:copy_size; memcpy(r->binbuf->buf + r->binbufpos,r->readbuf->buf + r->rpos,copy_size); size -= copy_size; r->rpos += copy_size; r->data_remain -= copy_size; r->binbufpos += copy_size; if(r->rpos >= r->readbuf->size && r->data_remain) { //当前buffer数据已经被读完,切换到下一个buffer r->rpos = 0; r->readbuf = buffer_acquire(r->readbuf,r->readbuf->next); } } } return addr; }
int32_t connection_start_recv(struct connection *c) { if(c->unpack_buf) return -10; c->unpack_buf = buffer_create_and_acquire(c->mt,NULL,BUFFER_SIZE); c->next_recv_buf = buffer_acquire(NULL,c->unpack_buf); c->next_recv_pos = c->unpack_pos = c->unpack_size = 0; c->wrecvbuf[0].iov_len = BUFFER_SIZE; c->wrecvbuf[0].iov_base = c->next_recv_buf->buf; c->recv_overlap.m_super.iovec_count = 1; c->recv_overlap.isUsed = 1; c->recv_overlap.m_super.iovec = c->wrecvbuf; return Post_Recv(c->socket,&c->recv_overlap.m_super); }
//接收相关函数 static inline void update_next_recv_pos(struct connection *c,int32_t bytestransfer) { uint32_t size; while(bytestransfer) { size = c->next_recv_buf->capacity - c->next_recv_pos; size = size > (uint32_t)bytestransfer ? (uint32_t)bytestransfer:size; c->next_recv_buf->size += size; c->next_recv_pos += size; bytestransfer -= size; if(c->next_recv_pos >= c->next_recv_buf->capacity) { if(!c->next_recv_buf->next) c->next_recv_buf->next = buffer_create_and_acquire(c->mt,NULL,BUFFER_SIZE); c->next_recv_buf = buffer_acquire(c->next_recv_buf,c->next_recv_buf->next); c->next_recv_pos = 0; } } }
static void wpacket_write(wpacket_t w,int8_t *addr,uint32_t size) { int8_t *ptr = addr; uint32_t copy_size; buffer_t tmp; uint8_t k; if(!w->writebuf) { /*wpacket是由rpacket构造的,这里执行写时拷贝, * 执行完后wpacket和构造时传入的rpacket不再共享buffer */ k = GetK(*w->len); w->factor = k; tmp = buffer_create_and_acquire(0,1 << k); wpacket_copy(w,tmp); w->begin_pos = 0; if(!w->raw) { w->len = (uint32_t*)tmp->buf; w->wpos = sizeof(*w->len); } w->buf = buffer_acquire(w->buf,tmp); w->writebuf = buffer_acquire(w->writebuf,w->buf); } while(size) { copy_size = w->buf->capacity - w->wpos; if(copy_size == 0) { wpacket_expand(w);//空间不足,扩展 copy_size = w->buf->capacity - w->wpos; } copy_size = copy_size > size ? size:copy_size; memcpy(w->writebuf->buf + w->wpos,ptr,copy_size); w->writebuf->size += copy_size; if(w->len) (*w->len) += copy_size; w->wpos += copy_size; ptr += copy_size; size -= copy_size; w->data_size += copy_size; } }
//接收相关函数 static inline void update_next_recv_pos(struct connection *c,int32_t _bytestransfer) { assert(_bytestransfer >= 0); uint32_t bytestransfer = (uint32_t)_bytestransfer; uint32_t size; do{ size = c->next_recv_buf->capacity - c->next_recv_pos; size = size > bytestransfer ? bytestransfer:size; c->next_recv_buf->size += size; c->next_recv_pos += size; bytestransfer -= size; if(c->next_recv_pos >= c->next_recv_buf->capacity) { if(!c->next_recv_buf->next) c->next_recv_buf->next = buffer_create_and_acquire(NULL,BUFFER_SIZE); c->next_recv_buf = buffer_acquire(c->next_recv_buf,c->next_recv_buf->next); c->next_recv_pos = 0; } }while(bytestransfer); }
wpacket_t wpacket_create(uint32_t size,uint8_t is_raw) { uint8_t k = GetK(size); wpacket_t w; size = 1 << k; w = LIST_POP(wpacket_t,g_wpacket_pool);//calloc(1,sizeof(*w)); if(!w) { printf("缓存不够了\n"); getchar(); exit(0); } //w = calloc(1,sizeof(*w)); w->factor = k; w->raw = is_raw; w->buf = buffer_create_and_acquire(0,size); w->writebuf = buffer_acquire(0,w->buf); w->begin_pos = 0; if(is_raw) { w->wpos = 0; w->len = 0; w->buf->size = 0; w->data_size = 0; } else { w->wpos = sizeof(w->len); w->len = (uint32_t*)w->buf->buf; *(w->len) = 0; w->buf->size = sizeof(w->len); w->data_size = sizeof(*(w->len)); } return w; }
void RecvFinish(int32_t bytestransfer,struct connection *c,uint32_t err_code) { uint32_t recv_size; uint32_t free_buffer_size; buffer_t buf; uint32_t pos; int32_t i = 0; do{ if(bytestransfer == 0) return; else if(bytestransfer < 0 && err_code != EAGAIN){ //printf("recv close\n"); if(c->status != SCLOSE){ c->status = SCLOSE; CloseSocket(c->socket); //被动关闭 c->cb_disconnect(c,err_code); } return; }else if(bytestransfer > 0){ int32_t total_size = 0; do{ c->last_recv = GetSystemMs64(); update_next_recv_pos(c,bytestransfer); c->unpack_size += bytestransfer; total_size += bytestransfer; if(!unpack(c)) return; buf = c->next_recv_buf; pos = c->next_recv_pos; recv_size = BUFFER_SIZE; i = 0; do { free_buffer_size = buf->capacity - pos; free_buffer_size = recv_size > free_buffer_size ? free_buffer_size:recv_size; c->wrecvbuf[i].iov_len = free_buffer_size; c->wrecvbuf[i].iov_base = buf->buf + pos; recv_size -= free_buffer_size; pos += free_buffer_size; if(recv_size && pos >= buf->capacity) { pos = 0; if(!buf->next) buf->next = buffer_create_and_acquire(NULL,BUFFER_SIZE); buf = buf->next; } ++i; }while(recv_size); c->recv_overlap.m_super.iovec_count = i; c->recv_overlap.m_super.iovec = c->wrecvbuf; if(total_size >= BUFFER_SIZE) { Post_Recv(c->socket,&c->recv_overlap.m_super); return; } else bytestransfer = Recv(c->socket,&c->recv_overlap.m_super,&err_code); }while(bytestransfer > 0); } }while(1); }
void RecvFinish(int32_t bytestransfer,st_io *io) { struct OVERLAPCONTEXT *OVERLAP = (struct OVERLAPCONTEXT *)io; struct connection *c = OVERLAP->c; uint32_t recv_size; uint32_t free_buffer_size; buffer_t buf; uint32_t pos; int32_t i = 0; uint32_t err_code = io->err_code; for(;;) { if(bytestransfer == 0 || (bytestransfer < 0 && err_code != EAGAIN)) { printf("recv close\n"); c->recv_overlap.isUsed = 0; c->is_close = 1; if(!c->send_overlap.isUsed) { //-1,passive close c->_on_disconnect(c,-1); } break; } else if(bytestransfer < 0 && err_code == EAGAIN) { break; } else { int32_t total_size = 0; while(bytestransfer > 0) { c->last_recv = GetCurrentMs(); //total_size += bytestransfer; update_next_recv_pos(c,bytestransfer); c->unpack_size += bytestransfer; total_size += bytestransfer; unpack(c); buf = c->next_recv_buf; pos = c->next_recv_pos; recv_size = BUFFER_SIZE; i = 0; while(recv_size) { free_buffer_size = buf->capacity - pos; free_buffer_size = recv_size > free_buffer_size ? free_buffer_size:recv_size; c->wrecvbuf[i].iov_len = free_buffer_size; c->wrecvbuf[i].iov_base = buf->buf + pos; recv_size -= free_buffer_size; pos += free_buffer_size; if(recv_size && pos >= buf->capacity) { pos = 0; if(!buf->next) buf->next = buffer_create_and_acquire(c->mt,NULL,BUFFER_SIZE); buf = buf->next; } ++i; } c->recv_overlap.isUsed = 1; c->recv_overlap.m_super.iovec_count = i; c->recv_overlap.m_super.iovec = c->wrecvbuf; if(total_size > 65536) { Post_Recv(c->socket,&c->recv_overlap.m_super); return; } else bytestransfer = Recv(c->socket,&c->recv_overlap.m_super,&err_code); } } } }
void RecvFinish(int32_t bytestransfer,st_io *io) { struct OVERLAPCONTEXT *OVERLAP = (struct OVERLAPCONTEXT *)io; struct connection *c = OVERLAP->c; rpacket_t r; uint32_t recv_size; uint32_t free_buffer_size; buffer_t buf; uint32_t pos; int32_t i = 0; uint32_t err_code = io->err_code; for(;;) { if(bytestransfer == 0 || bytestransfer < 0 && err_code != EAGAIN) { c->recv_overlap.isUsed = 0; if(!c->send_overlap.isUsed) { if(c->is_close == 1) { printf("RecvFinish is_close\n"); exit(0); } //-1,passive close c->_on_disconnect(c,-1); } break; } else if(bytestransfer < 0 && err_code == EAGAIN) { break; } else { while(bytestransfer > 0) { update_next_recv_pos(c,bytestransfer); c->unpack_size += bytestransfer; unpack(c); //while(r = unpack(c)) // c->_process_packet(c,r); //发起另一次读操作 buf = c->next_recv_buf; pos = c->next_recv_pos; recv_size = BUFFER_SIZE; i = 0; while(recv_size) { free_buffer_size = buf->capacity - pos; free_buffer_size = recv_size > free_buffer_size ? free_buffer_size:recv_size; c->wrecvbuf[i].iov_len = free_buffer_size; c->wrecvbuf[i].iov_base = buf->buf + pos; recv_size -= free_buffer_size; pos += free_buffer_size; if(recv_size && pos >= buf->capacity) { pos = 0; if(!buf->next) buf->next = buffer_create_and_acquire(c->mt,NULL,BUFFER_SIZE); buf = buf->next; } ++i; } c->recv_overlap.isUsed = 1; c->recv_overlap.m_super.iovec_count = i; c->recv_overlap.m_super.iovec = c->wrecvbuf; bytestransfer = WSARecv(c->socket,&c->recv_overlap.m_super,1,&err_code); } } } }