Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
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);
    }
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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);
}
Exemplo n.º 7
0
//接收相关函数
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;
		}
	}
}
Exemplo n.º 8
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;
	}
}
Exemplo n.º 9
0
//接收相关函数
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);
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
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);
}
Exemplo n.º 12
0
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);
			}
		}
	}
}
Exemplo n.º 13
0
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);
			}
		}
	}
}