zoukankan      html  css  js  c++  java
  • 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/
  • 相关阅读:
    爬取校园新闻首页的新闻的详情,使用正则表达式,函数抽离
    网络爬虫基础练习
    Mysql 使用 select into outfile
    Mysql 使用CMD 登陆
    使用Clean() 去掉由函数自动生成的字符串中的双引号
    Get Resultset from Oracle Stored procedure
    获取引用某个主键的所有外键的表
    Entity Framework 丢失数据链接的绑定,在已绑好的EDMX中提示“Choose Your Data Connection”
    添加MySql Metat Database 信息
    at System.Data.EntityClient.EntityConnection.GetFactory(String providerString)
  • 原文地址:https://www.cnblogs.com/bugutian/p/14596637.html
Copyright © 2011-2022 走看看