搜索了下往上的示例代码,写了个服务器 客户端 但还是有问题:
服务器的代码:
#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#ifndef WIN32
#include <netinet/in.h>
# ifdef _XOPEN_SOURCE_EXTENDED
# include <arpa/inet.h>
# endif
#include <sys/socket.h>
#endif
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
static void set_tcp_no_delay(evutil_socket_t fd)
{
int one = 1;
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
(const char*)&one, sizeof one);
}
static void signal_cb(evutil_socket_t fd, short what, void *arg)
{
struct event_base *base = (event_base*)arg;
printf("stop\n");
event_base_loopexit(base, NULL);
}
static void echo_read_cb(struct bufferevent *bev, void *ctx)
{
/* This callback is invoked when there is data to read on bev. */
struct evbuffer *input = bufferevent_get_input(bev);
struct evbuffer *output = bufferevent_get_output(bev);
/* Copy all the data from the input buffer to the output buffer. */
evbuffer_add_buffer(output, input);
}
char echo_str[] = "hello world!";
struct message
{
int total_size;
int id;
int size_;
char* data_;
message(int id, int size, char* data):id(id), size_(size), data_(NULL), total_size(0)
{
if (size_ > 0)
{
data_ = new char[size_];
memcpy(data_, data, size_);
}
total_size = sizeof(total_size) * 3 + size_;
}
~message()
{
if (data_)
{
delete []data_;
}
}
int get_size()
{
return total_size;
}
};
int send_times = 0;
static void echo_write_cb(struct bufferevent *bev, void *ctx)
{
if (send_times++ >= 1)
{
return;
}
message lmessage(10, sizeof(echo_str), echo_str);
/* This callback is invoked when there is data to read on bev. */
int fd = bufferevent_getfd(bev);
char* psend_data = new char[lmessage.get_size()];
memcpy(psend_data, &lmessage, lmessage.get_size());
bufferevent_write(bev, psend_data, lmessage.get_size());
printf("send buffer %d\n", lmessage.get_size());
delete []psend_data;
}
static void echo_event_cb(struct bufferevent *bev, short events, void *ctx)
{
struct evbuffer *output = bufferevent_get_output(bev);
size_t remain = evbuffer_get_length(output);
if (events & BEV_EVENT_ERROR) {
perror("Error from bufferevent");
}
if (events & (BEV_EVENT_EOF | BEV_EVENT_ERROR)) {
printf("closing, remain %zd\n", remain);
bufferevent_free(bev);
send_times = 0;
}
}
static void accept_conn_cb(struct evconnlistener *listener,
evutil_socket_t fd, struct sockaddr *address, int socklen,
void *ctx)
{
/* We got a new connection! Set up a bufferevent for it. */
struct event_base *base = evconnlistener_get_base(listener);
struct bufferevent *bev = bufferevent_socket_new(
base, fd, BEV_OPT_CLOSE_ON_FREE);
set_tcp_no_delay(fd);
bufferevent_setcb(bev, echo_read_cb, echo_write_cb, echo_event_cb, NULL);
bufferevent_enable(bev, EV_READ|EV_WRITE);
}
int main(int argc, char **argv)
{
#ifdef WIN32
WSADATA wsa_data;
WSAStartup(0x0201, &wsa_data);
#endif
struct event_base *base;
struct evconnlistener *listener;
struct sockaddr_in sin;
struct event *evstop;
int port = 9555;
if (argc > 1) {
port = atoi(argv[1]);
}
if (port<=0 || port>65535) {
puts("Invalid port");
return 1;
}
//signal(SIGPIPE, SIG_IGN);
base = event_base_new();
if (!base) {
puts("Couldn't open event base");
return 1;
}
//evstop = evsignal_new(base, SIGHUP, signal_cb, base);
//evsignal_add(evstop, NULL);
/* Clear the sockaddr before using it, in case there are extra
* * platform-specific fields that can mess us up. */
memset(&sin, 0, sizeof(sin));
/* This is an INET address */
sin.sin_family = AF_INET;
/* Listen on 0.0.0.0 */
sin.sin_addr.s_addr = htonl(0x7f000001);
/* Listen on the given port. */
sin.sin_port = htons(port);
listener = evconnlistener_new_bind(base, accept_conn_cb, NULL,
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1,
(struct sockaddr*)&sin, sizeof(sin));
if (!listener) {
perror("Couldn't create listener");
return 1;
}
event_base_dispatch(base);
evconnlistener_free(listener);
event_free(evstop);
event_base_free(base);
return 0;
}
客户端:
#include <event2/event.h>
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#ifndef WIN32
#include <netinet/in.h>
# ifdef _XOPEN_SOURCE_EXTENDED
# include <arpa/inet.h>
# endif
#include <sys/socket.h>
#endif
#include <string.h>
#include <stdlib.h>
long long total_bytes_read = 0;
long long total_messages_read = 0;
static void set_tcp_no_delay(evutil_socket_t fd)
{
int one = 1;
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
(const char*)&one, sizeof one);
}
static void timeoutcb(evutil_socket_t fd, short what, void *arg)
{
struct event_base *base = (event_base *)arg;
printf("timeout\n");
event_base_loopexit(base, NULL);
}
struct message
{
int id;
int size_;
char* data_;
message(int id, int size, char* data):id(id), size_(size), data_(NULL)
{
if (size_ > 0)
{
data_ = new char[size_];
memcpy(data_, data, size_);
}
}
~message()
{
if (data_)
{
delete []data_;
}
}
int get_size()
{
return sizeof(id) + sizeof(size_) + size_;
}
};
static void readcb(struct bufferevent *bev, void *ctx)
{
char* line = new char[1024];
int buf_len = evbuffer_get_length(bufferevent_get_input(bev));
if (buf_len >= sizeof(int))
{
int total_size = 0;
int size = bufferevent_read(bev, line, buf_len);
if (size == 25)
{
total_size = *(int*)line;
line += sizeof(int);
int msgid = *(int*)line;
line += sizeof(msgid);
int msg_size = *(int*)line;
line += sizeof(msg_size);
char* msg_data = new char[msg_size];
memcpy(msg_data, line, msg_size);
//printf("get total_size:%d, msgid %d, msg_size:%d, msg_data %s", total_size, msgid, msg_size, msg_data);
delete []msg_data;
}
}
delete []line;
//int n;
//evutil_socket_t fd = bufferevent_getfd(bev);
//int size = bufferevent_read(bev, line, sizeof(line));
//if (size > 0)
//{
// printf("read from server with data :%s\n", line);
//}
}
static void eventcb(struct bufferevent *bev, short events, void *ptr)
{
if (events & BEV_EVENT_CONNECTED) {
evutil_socket_t fd = bufferevent_getfd(bev);
set_tcp_no_delay(fd);
} else if (events & BEV_EVENT_ERROR) {
printf("NOT Connected\n");
}
}
int main(int argc, char **argv)
{
#ifdef WIN32
WSADATA wsa_data;
WSAStartup(0x0201, &wsa_data);
#endif
struct event_base *base;
struct bufferevent **bevs;
struct sockaddr_in sin;
struct event *evtimeout;
struct timeval timeout;
int i;
//if (argc != 5) {
// fprintf(stderr, "Usage: client <port> <blocksize> ");
// fprintf(stderr, "<sessions> <time>\n");
// return 1;
//}
int port = 9555;
int block_size = 1024;
int session_count = 1;
int seconds = 10000;
timeout.tv_sec = seconds;
timeout.tv_usec = 0;
base = event_base_new();
if (!base) {
puts("Couldn't open event base");
return 1;
}
char* message = (char*)malloc(block_size);
for (i = 0; i < block_size; ++i) {
message[i] = i % 128;
}
evtimeout = evtimer_new(base, timeoutcb, base);
evtimer_add(evtimeout, &timeout);
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */
sin.sin_port = htons(port);
bevs = (bufferevent**)malloc(session_count * sizeof(struct bufferevent *));
for (i = 0; i < session_count; ++i) {
struct bufferevent *bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
bufferevent_setcb(bev, readcb, NULL, eventcb, NULL);
bufferevent_enable(bev, EV_READ|EV_WRITE);
evbuffer_add(bufferevent_get_output(bev), message, block_size);
if (bufferevent_socket_connect(bev,
(struct sockaddr *)&sin, sizeof(sin)) < 0) {
/* Error starting connection */
bufferevent_free(bev);
puts("error connect");
return -1;
}
bevs[i] = bev;
}
event_base_dispatch(base);
for (i = 0; i < session_count; ++i) {
bufferevent_free(bevs[i]);
}
free(bevs);
event_free(evtimeout);
event_base_free(base);
free(message);
printf("%zd total bytes read\n", total_bytes_read);
printf("%zd total messages read\n", total_messages_read);
printf("%.3f average messages size\n",
(double)total_bytes_read / total_messages_read);
printf("%.3f MiB/s throughtput\n",
(double)total_bytes_read / (timeout.tv_sec * 1024 * 1024));
return 0;
}