农业基本建设项目信息网站,代练平台,wordpress 安装配置,免费微网站建设平台C Enet通信封装 接口封装使用举例 Enet底层封装的是UDP通信#xff0c;本文介绍了enet如何实现可靠udp传输的代码封装 接口封装
1)User_Enet_Listen监听端口函数
int User_Enet_Listen(const char *ip, int port, ENetHost **host)
{ ENetAddress address; if(!strcmp(i… C Enet通信封装 接口封装使用举例 Enet底层封装的是UDP通信本文介绍了enet如何实现可靠udp传输的代码封装 接口封装
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(0ret){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(*peerNULL){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 _DEBUGchar 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 _DEBUGchar 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);#endifENetEvent 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 0ret ? 1 : -1;fprintf(stderr, enet_host_service with timeout %d %s, peer-roundTripTime, 1ret?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(NULLpacket){ 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(-1User_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(0ret cnttimeout){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