1)User_Enet_Listen监听端口函数
int User_Enet_Listen(const char *ip, int port, ENetHost **host)
{
ENetAddress address;
if(!strcmp(ip, "*"))
ip = "0.0.0.0";
if(enet_address_set_host_ip(&address, ip)){
fprintf(stderr, "enet_address_set_host_ip %s fail", ip);
return -1;
}
address.port = port;
assert(host);
*host = enet_host_create(&address, 1, 1, 0, 0);
if(NULL==*host){
fprintf(stderr, "enet_host_create %s:%d fail", address.host, address.port);
return -1;
}
int size = 1024*1024*1024;
if(enet_socket_set_option((*host)->socket, ENET_SOCKOPT_RCVBUF, size)){
fprintf(stderr, "enet set server socket rcvbuf %d bytes fail", size);
}
return 0;
}
2)User_Enet_Accept接受链接函数
int User_Enet_Accept(ENetHost *host, unsigned int timeout, ENetPeer **peer)
{
int ret;
ENetEvent event;
ret = enet_host_service(host, &event, timeout);
if(ret > 0){
if(event.type != ENET_EVENT_TYPE_CONNECT){
if(event.type == ENET_EVENT_TYPE_RECEIVE)
enet_packet_destroy(event.packet);
fprintf(stderr, "enet_host_service event type %d is not connect", event.type);
return -1;
}
assert(peer);
*peer = event.peer;
}else if(0==ret){
fprintf(stderr, "enet_host_service timeout %d", timeout);
return -1;
}else{
fprintf(stderr, "enet_host_service fail");
return -1;
}
return 0;
}
3)User_Enet_Connect建立连接函数
int User_Enet_Connect(const char *srv_ip, int srv_port, unsigned int conn_timeout, unsigned int rw_timeout, ENetHost **host, ENetPeer **peer)
{
assert(host);
*host = enet_host_create(NULL, 1, 1, 0, 0);
if(NULL==*host){
fprintf(stderr, "enet_host_create fail");
goto fail;
}
if(enet_socket_set_option((*host)->socket, ENET_SOCKOPT_RCVBUF, 1024*1024*1024)){
fprintf(stderr, "enet set server socket rcvbuf 1M bytes fail");
}
ENetAddress srv_addr;
if(enet_address_set_host_ip(&srv_addr, srv_ip)){
fprintf(stderr, "enet_address_set_host_ip %s fail", srv_ip);
goto fail;
}
srv_addr.port = srv_port;
assert(peer);
*peer = enet_host_connect(*host, &srv_addr, 1, 0);
if(*peer==NULL){
fprintf(stderr, "enet_host_connect %s:%d fail", srv_ip, srv_port);
goto fail;
}
enet_peer_timeout(*peer, 0, rw_timeout, rw_timeout);
int cnt = 0;
ENetEvent event;
while(1){
ret = enet_host_service(*host, &event, 1);
if(ret == 0){
if(++cnt >= conn_timeout){
fprintf(stderr, "enet_host_service timeout %d", conn_timeout);
goto fail;
}
}else if(ret > 0){
if(event.type != ENET_EVENT_TYPE_CONNECT){
fprintf(stderr, "enet_host_service event type %d is not connect", event.type);
goto fail;
}
break; //connect successfully
}else{
fprintf(stderr, "enet_host_service fail");
goto fail;
}
}
#ifdef _DEBUG
char local_ip[16], foreign_ip[16];
ENetAddress local_addr;
enet_socket_get_address((*host)->socket, &local_addr);
enet_address_get_host_ip(&local_addr, local_ip, sizeof(local_ip));
enet_address_get_host_ip(&(*peer)->address, foreign_ip, sizeof(foreign_ip));
printf("%s:%d connected to %s:%d", local_ip, loca_addr.port, foreign_ip, (*peer)->address.port);
#endif
return 0;
fail:
if(*host) enet_host_destroy(*host);
return -1;
}
4)User_Enet_DisConnect断开连接函数
int User_Enet_DisConnect(ENetHost *host, ENetPeer *peer)
{
int ret;
#ifdef _DEBUG
char local_ip[16], foreign_ip[16];
ENetAddress local_addr;
enet_socket_get_address(host->socket, &local_addr);
enet_address_get_host_ip(&local_addr, local_ip, sizeof(local_ip));
enet_address_get_host_ip(&peer->address, foreign_ip, sizeof(foreign_ip));
printf("%s:%d is disconnected from %s:%d", local_ip, local_addr.port, foreign_ip, peer->address.port);
#endif
ENetEvent event;
enet_peer_disconnect(peer, 0);
while((ret = enet_host_service(host, &event, peer->roundTripTime)) > 0){
switch (event.type){
case ENET_EVENT_TYPE_RECEIVE:
enet_packet_destroy (event.packet);
break;
case ENET_EVENT_TYPE_DISCONNECT:
ret = 0;
goto disconn_ok;
}
}
ret = 0==ret ? 1 : -1;
fprintf(stderr, "enet_host_service with timeout %d %s", peer->roundTripTime, 1==ret?"timeout":"failure");
enet_peer_reset(conn->peer);
disconn_ok:
enet_host_destroy(host);
return ret;
}
5)User_Enet_SendMsg发送数据函数
int User_Enet_SendMsg(ENetHost *host, ENetPeer *peer, ENetPacket *packet)
{
int ret;
if(enet_peer_send(peer, 0, packet)){
fprintf(stderr, "enet send packet %lu bytes to peer fail", packet->dataLength);
return -1;
}
ret = enet_host_service(host, NULL, peer->roundTripTime);
if(ret >= 0){
if(peer->state == ENET_PEER_STATE_ZOMBIE){
fprintf(stderr, "enet peer state is zombie");
return -1;
}
return packet->dataLength;
}else{
fprintf(stderr, "enet host service %u millsecond failure", peer->roundTripTime);
return -1;
}
}
int User_Enet_Send(ENetHost *host, ENetPeer *peer, const void *buf, size_t len)
{
int ret;
ENetPacket *packet = enet_packet_create(buf, len, ENET_PACKET_FLAG_RELIABLE);
if(NULL==packet){
fprintf(stderr, "enet create packet %lu bytes fail", sizeof(int)+len);
return -1;
}
return User_Enet_SendMsg(host, peer, packet);
}
6)User_Enet_RecvMsg接收数据函数
int User_Enet_RecvMsg(ENetHost *host, ENetPeer *peer, ENetPacket **packet, unsigned int timeout)
{
int ret;
ENetEvent event;
ret = enet_host_service(host, &event, timeout);
if(ret > 0){
if(event.peer != peer){
fprintf(stderr, "enet receive peer is not matched");
goto fail;
}
if(event.type != ENET_EVENT_TYPE_RECEIVE){
fprintf(stderr, "enet receive event type %d is not ENET_EVENT_TYPE_RECEIVE", event.type);
goto fail;
}
*packet = event.packet;
return (*packet)->dataLength;
fail:
enet_packet_destroy(event.packet);
return -1;
}else {
fprintf(stderr, "enet receive %u millsecond %s", timeout, ret?"failure":"timeout");
return -1;
}
}
int User_Enet_Recv(ENetHost *host, ENetPeer *peer, void *buf, size_t maxlen, unsigned int timeout)
{
ENetPacket *packet;
if(-1==User_Enet_RecvMsg(host, peer, &packet, timeout))
return -1;
if(packet->dataLength > maxlen) {
fprintf(stderr, "enet packet data length %d is greater than maxlen %lu", packet->dataLength, maxlen);
return -1;
}
memcpy(buf, packet->data, packet->dataLength);
enet_packet_destroy(packet);
return packet->dataLength;
}
7)User_Enet__WaitAck 等待所有确认函数
发送数据的确认,需根据对端状态判断是否断线
int User_Enet__WaitAck (ENetHost *host, ENetPeer *peer, unsigned int timeout)
{
int ret, cnt = 0;
while((ret = enet_host_service(host, NULL, 1)) >= 0){
if(enet_peer_is_empty_sent_reliable_commands(peer, 0,
ENET_PROTOCOL_COMMAND_SEND_RELIABLE|ENET_PROTOCOL_COMMAND_SEND_FRAGMENT))
return 0;
if(peer->state == ENET_PEER_STATE_ZOMBIE){
fprintf(stderr, "enet peer state is zombie");
return -1;
}
if(0==ret && ++cnt>=timeout){
return 1;
}
}
fprintf(stderr, "enet host service fail");
return -1;
}
客户端:
User_Enet_Connect->User_Enet_SendMsg或User_Enet_Send->User_Enet_WaitAck
服务端:
User_Enet_Listen->User_Enet_Accept->User_Enet_Recv或是User_Enet_RecvMsg