Discussion:
some connections of IOCP client are refused by IOCP server
(too old to reply)
jason
2014-09-19 08:10:23 UTC
Permalink
Raw Message
I write a simple IOCP server, and a IOCP Client, and do the following test
at the same machine.

IOCP Client creates 1000 buffer events to connect to IOCP server at start,
but some of them are refused by IOCP server.

Error code is 10061.



// test_libevent_server.cpp : Defines the entry point for the console
application.

//



#include "stdafx.h"

#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>

#include <event2/thread.h>

#include <map>



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 _tmain(int argc, _TCHAR* argv[])

{



struct event_base *base;

struct evconnlistener *listener;

struct event *signal_event;



struct sockaddr_in sin;

#ifdef WIN32

WSADATA wsa_data;

WSAStartup(0x0202, &wsa_data);

#endif

event_config* pConfig = event_config_new();

event_config_set_flag( pConfig, EVENT_BASE_FLAG_STARTUP_IOCP );

evthread_use_windows_threads();

base = event_base_new_with_config( pConfig );

event_config_free( pConfig );



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 = ( event_base* )user_data;

struct bufferevent *bev;



bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE |
BEV_OPT_THREADSAFE);

if (!bev) {

fprintf(stderr, "Error constructing bufferevent!");

event_base_loopbreak(base);

return;

}



static int s_iCount = 0;

printf("count=%d,connected!\n",++s_iCount);



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) {

static int s_iCount = 0;

//printf("count=%d,flushed answer\n",++s_iCount);

//bufferevent_free(bev);

}

}



static void

conn_eventcb(struct bufferevent *bev, short events, void *user_data)

{

if (events & BEV_EVENT_EOF) {

static int s_iCount = 0;

printf("count=%d,Connection closed.\n", ++s_iCount);

} else if (events & BEV_EVENT_ERROR) {

static int s_iCount = 0;

printf("count=%d,Got an error on the connection: %s\n",

++s_iCount, strerror(errno));/*XXX win32*/

}else if (events & BEV_EVENT_CONNECTED) {

static int s_iCount = 0;

printf("count=%d,connect!\n",++s_iCount);/*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 = ( event_base* )user_data;

struct timeval delay = { 2, 0 };



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



event_base_loopexit(base, &delay);

}



// test_libevent_Client.cpp : Defines the entry point for the console
application.

//



#include "stdafx.h"

#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>

#include <event2/thread.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 _tmain(int argc, _TCHAR* argv[])

{

struct event_base *base;

struct evconnlistener *listener;

struct event *signal_event;



struct sockaddr_in sin;

#ifdef WIN32

WSADATA wsa_data;

WSAStartup(0x0202, &wsa_data);

#endif

event_config* pConfig = event_config_new();

event_config_set_flag( pConfig, EVENT_BASE_FLAG_STARTUP_IOCP );

evthread_use_windows_threads();

base = event_base_new_with_config( pConfig );

event_config_free( pConfig );



if (!base) {

fprintf(stderr, "Could not initialize libevent!\n");

return 1;

}



memset(&sin, 0, sizeof(sin));

sin.sin_family = AF_INET;

sin.sin_addr.S_un.S_addr = htonl(0x7f000001);

sin.sin_port = htons(PORT);



const int NUM_BUFFER_EVENT = 2000;

bufferevent* pBufferEvents[ NUM_BUFFER_EVENT ] = { 0 };

for( int i = 0; i < NUM_BUFFER_EVENT; ++i )

{

pBufferEvents[ i ] = bufferevent_socket_new( base, -1,
BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE );



bufferevent_setcb( pBufferEvents[ i ], NULL, conn_writecb,
conn_eventcb, NULL );

bufferevent_enable( pBufferEvents[ i ], EV_WRITE | EV_READ );



if( 0 != bufferevent_socket_connect(

pBufferEvents[ i ],

( sockaddr* )&sin,

sizeof( sin ) ) )

{

return 0;

}

}



event_base_dispatch(base);



for( int i = 0; i < NUM_BUFFER_EVENT; ++i )

{

if( pBufferEvents[ i ] )

{

bufferevent_free( pBufferEvents[ i ] );

}

}



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 = ( event_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) {

static int s_iCount = 0;

printf("count=%d,Connection closed.\n", ++s_iCount);

} else if (events & BEV_EVENT_ERROR) {

static int s_iCount = 0;

printf("count=%d,Got an error on the connection: %d\n",

++s_iCount, WSAGetLastError());/*XXX win32*/

}else if (events & BEV_EVENT_CONNECTED) {

static int s_iCount = 0;

printf("count=%d,connect!\n",++s_iCount);/*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 = ( event_base* )user_data;

struct timeval delay = { 2, 0 };



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



event_base_loopexit(base, &delay);

}



Could you tell me why?

Loading...