Libevent library notes (1) download and compile, test demo

1. Download and compile

1.1. Download

Official website: http://libevent.org/
1.4 and 2.x series versions, 1.4 is relatively old, but the source code is simple, suitable for learning;
2.x is relatively new, it is recommended to use the 2.x version when using it, which is not compatible with the 1.4 version interface .
The current status of the 2 series of versions (2020.02.09)
libevent-release-1.4.15-stable.tar.gz
libevent-2.1.11-stable.tar.gz

1.2. Compile

1.2.1. Description

./configure Check the installation environment and generate makefile
make Generate target files and executable files
sudo make install Copy relevant header files and library files to the system directory

1.2.2.Ubuntu platform compilation and installation

Here take the 2.11 version as an example to
decompress
tar -zxvf libevent-2.1.11-stable.tar.gz

Insert picture description here
Enter the decompressed directory
cd libevent-2.1.11-stable/
./configure #Check the installation environment and generate makefile
make #Generate target files and executable files
sudo make install #Copy relevant header files and library files to the system directory
Insert picture description here
prompt library It has been installed to /usr/local/lib, you
can enter the directory to view related libraries.
Insert picture description here
In addition, the header file is located in /usr/local/include,
Insert picture description here
where event2 is a directory.
Insert picture description here

1.2.3. Compile and test the demo

Enter the sample directory:
cd sample
Insert picture description here

$ gcc -o hello hello-world.c -levent
Run the demo:
./hello
Run a client connection
$nc 127.0.0.1 9995

Insert picture description here
Insert picture description here
After the client connects to the server, the server responds with hello, and after the world, immediately waved FIN, and the client responded with ACK.
Use wireshark to capture packets to view
Insert picture description here
Insert picture description here

1.2.4. Demo code

You can roughly see that the listening port number is 9995
and interact with a MESSAGE (the string "Hello, World!\n";)

/*
  This example program provides a trivial server program that listens for TCP
  connections on port 9995.  When they arrive, it writes a short message to
  each client connection, and closes each connection once it is flushed.

  Where possible, it exits cleanly in response to a SIGINT (ctrl-c).
*/


#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#ifndef _WIN32
#include <netinet/in.h>
# ifdef _XOPEN_SOURCE_EXTENDED
#  include <arpa/inet.h>
# endif
#include <sys/socket.h>
#endif

#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <event2/listener.h>
#include <event2/util.h>
#include <event2/event.h>

static const char MESSAGE[] = "Hello, World!\n";

static const int PORT = 9995;

static void listener_cb(struct evconnlistener *, evutil_socket_t,
    struct sockaddr *, int socklen, void *);
static void conn_writecb(struct bufferevent *, void *);
static void conn_eventcb(struct bufferevent *, short, void *);
static void signal_cb(evutil_socket_t, short, void *);

int
main(int argc, char **argv)
{
    
    
	struct event_base *base;
	struct evconnlistener *listener;
	struct event *signal_event;

	struct sockaddr_in sin;
#ifdef _WIN32
	WSADATA wsa_data;
	WSAStartup(0x0201, &wsa_data);
#endif

	base = event_base_new();
	if (!base) {
    
    
		fprintf(stderr, "Could not initialize libevent!\n");
		return 1;
	}

	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);

	listener = evconnlistener_new_bind(base, listener_cb, (void *)base,
	    LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1,
	    (struct sockaddr*)&sin,
	    sizeof(sin));

	if (!listener) {
    
    
		fprintf(stderr, "Could not create a listener!\n");
		return 1;
	}

	signal_event = evsignal_new(base, SIGINT, signal_cb, (void *)base);

	if (!signal_event || event_add(signal_event, NULL)<0) {
    
    
		fprintf(stderr, "Could not create/add a signal event!\n");
		return 1;
	}

	event_base_dispatch(base);

	evconnlistener_free(listener);
	event_free(signal_event);
	event_base_free(base);

	printf("done\n");
	return 0;
}

static void
listener_cb(struct evconnlistener *listener, evutil_socket_t fd,
    struct sockaddr *sa, int socklen, void *user_data)
{
    
    
	struct event_base *base = user_data;
	struct bufferevent *bev;

	bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
	if (!bev) {
    
    
		fprintf(stderr, "Error constructing bufferevent!");
		event_base_loopbreak(base);
		return;
	}
	bufferevent_setcb(bev, NULL, conn_writecb, conn_eventcb, NULL);
	bufferevent_enable(bev, EV_WRITE);
	bufferevent_disable(bev, EV_READ);

	bufferevent_write(bev, MESSAGE, strlen(MESSAGE));
}

static void
conn_writecb(struct bufferevent *bev, void *user_data)
{
    
    
	struct evbuffer *output = bufferevent_get_output(bev);
	if (evbuffer_get_length(output) == 0) {
    
    
		printf("flushed answer\n");
		bufferevent_free(bev);
	}
}

static void
conn_eventcb(struct bufferevent *bev, short events, void *user_data)
{
    
    
	if (events & BEV_EVENT_EOF) {
    
    
		printf("Connection closed.\n");
	} else if (events & BEV_EVENT_ERROR) {
    
    
		printf("Got an error on the connection: %s\n",
		    strerror(errno));/*XXX win32*/
	}
	/* None of the other events can happen here, since we haven't enabled
	 * timeouts */
	bufferevent_free(bev);
}

static void
signal_cb(evutil_socket_t sig, short events, void *user_data)
{
    
    
	struct event_base *base = user_data;
	struct timeval delay = {
    
     2, 0 };

	printf("Caught an interrupt signal; exiting cleanly in two seconds.\n");

	event_base_loopexit(base, &delay);
}

2. Appendix nc command

Function: short for netcat, it is a simple and useful tool. It can be used for various TCP and UDP monitoring and connection testing purposes.
Available parameters
$ nc -help
OpenBSD netcat (Debian patchlevel 1.187-1ubuntu0.1)
usage: nc [-46CDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl]
[-m minttl] [-O length] [ -P proxy_username] [-p source_port]
[-q seconds] [-s source] [-T keyword] [-V rtable] [-W recvlimit] [-w timeout]
[-X proxy_protocol] [-x proxy_address[: Port]] [Where do you want] [Port]
the Command the Summary:
-4 the Use the IPv4
-6 the Use the IPv6
-b Broadcast the Allow
-C-Line Ending the Send CRLF AS
-D the Enable Debug Socket Option The
-d the Detach from stdin
-F Pass Socket FD
- h This help text
-I length TCP receive buffer length
-i interval Delay interval for lines sent, ports scanned
-k Keep inbound sockets open for multiple connects
-l Listen mode, for inbound connects
-M ttl Outgoing TTL / Hop Limit
-m minttl Minimum incoming TTL / Hop Limit
-N Shutdown the network socket after EOF on stdin
-n Suppress name/port resolutions
-O length TCP send buffer length
-P proxyuser Username for proxy authentication
-p port Specify local port for remote connects
-q secs quit after EOF on stdin and delay of secs
-r Randomize remote ports
-S Enable the TCP MD5 signature option
-s source Local source address
-T keyword TOS value
-t Answer TELNET negotiation
-U Use UNIX domain socket
-u UDP mode
-V rtable Specify alternate routing table
-v Verbose
-W recvlimit Terminate after receiving a number of packets
-w timeout Timeout for connects and final net reads
-X proto Proxy protocol: “4”, “5” (SOCKS) or “connect”
-x addr[:port] Specify proxy address and port
-Z DCCP mode
-z Zero-I/O mode [used for scanning]
Port numbers can be individual or ranges: lo-hi [inclusive]

Guess you like

Origin blog.csdn.net/skytering/article/details/104242754