ENET程序实例

ENet的目的是提供一个相对轻量、简单、稳定的基于UDP的网络通信。
主要特色就是提供了可选的、可靠的、顺序传送的数据包。

准备

下载:http://enet.bespin.org/Downloads.html
编译安装

./configure --prefix=/usr/local/enet
make
make install

示例代码

enet_server.cpp

代码:

#include <iostream>
#include <enet/enet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

void run()
{
    ENetAddress address;
    ENetHost * server;
    /* Bind the server to the default localhost.     */
    /* A specific host address can be specified by   */
    /* enet_address_set_host (& address, "x.x.x.x"); */
    address.host = ENET_HOST_ANY;
    /* Bind the server to port 1234. */
    address.port = 12345;
    server = enet_host_create (& address /* the address to bind the server host to */, 
                                 32      /* allow up to 32 clients and/or outgoing connections */,
                                  2      /* allow up to 2 channels to be used, 0 and 1 */,
                                  0      /* assume any amount of incoming bandwidth */,
                                  0      /* assume any amount of outgoing bandwidth */);
    if (server == NULL)
    {
        fprintf (stderr, 
                 "An error occurred while trying to create an ENet server host.
");
        exit (EXIT_FAILURE);
    }
    
    ENetEvent event;
    /* Wait up to 1000 milliseconds for an event. */
    while (enet_host_service (server, & event, 1000) >= 0)
    {
        switch (event.type)
        {
        case ENET_EVENT_TYPE_CONNECT:
            printf ("A new client connected from %x:%u.
", 
                    event.peer -> address.host,
                    event.peer -> address.port);
            /* Store any relevant client information here. */
            //event.peer -> data = "Client information";
			event.peer -> data = new char[10];
			strcpy ((char*)(event.peer -> data), "foo1");
            break;
        case ENET_EVENT_TYPE_RECEIVE:
            printf ("From %s,%u[len=%u]: %s
",
                    event.peer -> data,
                    event.channelID,
                    event.packet -> dataLength,
                    event.packet -> data);
            /* Clean up the packet now that we're done using it. */
			enet_peer_send (event.peer, 0, event.packet);
			/* One could just use enet_host_service() instead. */
			enet_host_flush (server);
            enet_packet_destroy (event.packet);
            
            break;
           
        case ENET_EVENT_TYPE_DISCONNECT:
            printf ("%s disconnected.
", event.peer -> data);
            /* Reset the peer's client information. */
            event.peer -> data = NULL;
        }
    }
}

int main()
{
    if (enet_initialize () != 0)
    {
        fprintf (stderr, "An error occurred while initializing ENet.
");
        return EXIT_FAILURE;
    }
	run();
    
    return 0;
}

编译:

g++ -g e_server.cpp -o e_server -I /usr/local/enet/include/ /usr/local/enet/lib/libenet.a

enet_client

代码:

#include <iostream>
#include <enet/enet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

void run()
{
	ENetHost * client;
	client = enet_host_create (NULL /* create a client host */,
				1 /* only allow 1 outgoing connection */,
				2 /* allow up 2 channels to be used, 0 and 1 */,
				0 /* assume any amount of incoming bandwidth */,
				0 /* assume any amount of outgoing bandwidth */);
	if (client == NULL)
	{
		fprintf (stderr, 
				 "An error occurred while trying to create an ENet client host.
");
		exit (EXIT_FAILURE);
	}
	
	ENetAddress address;
	ENetEvent event;
	ENetPeer *peer;
	/* Connect to some.server.net:1234. */
	enet_address_set_host (& address, "192.168.0.123");
	address.port = 12345;
	/* Initiate the connection, allocating the two channels 0 and 1. */
	peer = enet_host_connect (client, & address, 2, 0);    
	if (peer == NULL)
	{
	   fprintf (stderr, 
				"No available peers for initiating an ENet connection.
");
	   return ;
	}
	ENetPacket * packet = enet_packet_create ("packet", 
											  strlen ("packet") + 1, 
											  ENET_PACKET_FLAG_RELIABLE);
	/* Extend the packet so and append the string "foo", so it now */
	/* contains "packetfoo"                                      */
	enet_packet_resize (packet, strlen ("packetfoo") + 1);
	strcpy ((char*)(& packet -> data [strlen ("packet")]), "foo");
	
	/* Wait up to 5 seconds for the connection attempt to succeed. */
	if (enet_host_service (client, & event, 5000) > 0 &&
		event.type == ENET_EVENT_TYPE_CONNECT)
	{
		printf ("Connection to some.server.net:1234 succeeded.");
		/* Create a reliable packet of size 7 containing "packet" */
		/* Send the packet to the peer over channel id 0. */
		/* One could also broadcast the packet by         */
		/* enet_host_broadcast (host, 0, packet);         */
		enet_peer_send (peer, 0, packet);
		/* One could just use enet_host_service() instead. */
		enet_host_flush (client);
		event.peer -> data = new char[10];
		strcpy ((char*)(event.peer -> data), "foo2");
	}
	else
	{
		enet_peer_reset (peer);
		printf ("Connection to some.server.net:1234 failed.");
		return ;
	}
	char msg[200] = {0};
	/* Wait up to 5 seconds for the connection attempt to succeed. */
    while (enet_host_service (client, & event, 5000) >= 0)
    {
        switch (event.type)
        {
        case ENET_EVENT_TYPE_RECEIVE:
            printf ("From %s,%u[len=%u]: %s
",
                    event.peer -> data,
                    event.channelID,
                    event.packet -> dataLength,
                    event.packet -> data);
            /* Clean up the packet now that we're done using it. */
            //enet_packet_destroy (event.packet);
       
            break;
           
        case ENET_EVENT_TYPE_DISCONNECT:
            printf ("%s disconnected.
", event.peer -> data);
            /* Reset the peer's client information. */
            event.peer -> data = NULL;
        }
		/************* 
		// enet应该放在单独的线程里跑,scanf阻塞后会,影响enet_host_service发送心跳
		// 心跳1s一次,如果5s内没有心跳,服务端会提示连接断开
		scanf("%s",msg);
		enet_packet_resize (packet, strlen (msg) + 1);
		strcpy ((char*)( packet -> data ), msg);
		enet_peer_send (peer, 0, packet);
		enet_host_flush (client);*/
    }
}

int main()
{
    if (enet_initialize () != 0)
    {
        fprintf (stderr, "An error occurred while initializing ENet.
");
        return EXIT_FAILURE;
    }
	run();
    
    return 0;
}

编译:

g++ -g e_client.cpp -o e_client -I /usr/local/enet/include/ /usr/local/enet/lib/libenet.a

执行结果

自己把IP“192.168.0.123”改一下,编译之后直接运行即可。
服务端:

$ ./e_server 
A new client connected from 870fa8c0:41543.
From foo1,0[len=10]: packetfoo
From foo1,0[len=4]: ads
From foo1,0[len=6]: fadsf

客户端:

$ ./e_client 
Connection to some.server.net:1234 succeeded.From foo2,0[len=10]: packetfoo
1
From foo2,0[len=2]: 1
1
From foo2,0[len=2]: 1
转载请注明来源:https://www.cnblogs.com/bugutian/
原文地址:https://www.cnblogs.com/bugutian/p/14596637.html