示例#1
0
void net_poll_status_procedure()
{
  if(net_link_status==NETDEV_LINKED)
  {
  if(dhcp_new_ip_flag==0)//dhcp 无效
  {
    net_ip_flag=0;//ip无效
    if(net_socket_status!=SOCKET_CLOSED)
    {
     net_socket_close();//关闭net app 重新开始
    }
  }
  else
  { 
   if(dhcp_new_ip_flag!=net_ip_flag)//ip需要更新
   {   
    net_socket_param_refresh();//更新ip等资源
    net_ip_flag=dhcp_new_ip_flag;//net ip    
   if(net_socket_status!=SOCKET_CLOSED)
   {
    net_socket_close();//关闭net app 重新开始
    }
   }
  }
  /***********************/
  if(net_socket_status==SOCKET_UDP)//-------------------
  {
    //todo

  }
  if(net_socket_status==SOCKET_INIT)//tcp init
  {
   net_socket_connect(); 
  }

  if(net_socket_status==SOCKET_CLOSED || net_socket_status==SOCKET_CLOSE_WAIT)//如果netsocket 是关闭的或者半关闭重新初始化连接
  {
   if(dhcp_new_ip_flag==net_ip_flag && net_ip_flag!=0  )//如果ip有效
   {
    net_socket_init();     
    net_socket_open();//打开当前net socket 
   }
  } 
  if(net_ip_comflict)
  {
     net_ip_comflict=FALSE;//使IP冲突无效
     net_ip_flag=0;//使ip无效  
     hal_net_device_software_reset();//如果ip冲突 就重启设备
  }
 }
 else//断开link 就关闭net socket
 {   
   if(net_socket_status!=SOCKET_CLOSED)//-----------------
   {
   net_ip_comflict=FALSE;//使IP冲突无效
   net_ip_flag=0;//使ip无效  
   net_socket_close();//关闭当前net socket  
   }
 }
}
示例#2
0
void en_socket_close(int fd, int fd1) {
	if (fd != -1) {
		net_socket_close(fd);
	}
	if (fd1 != -1) {
		net_socket_close(fd1);
	}
}
示例#3
0
void loax_server_delete(loax_server_t** _self)
{
	assert(_self);

	loax_server_t* self = *_self;
	if(self)
	{
		LOGD("debug");
		net_socket_close(&self->socket_event);
		net_socket_close(&self->socket_render);
		free(self);
		*_self = NULL;
		g_server = NULL;
	}
}
示例#4
0
void net_ep_close_i(net_ep_t ep, net_ep_event_t ev) {
    assert(ep);
    assert(ev == net_ep_event_close_by_user
           || ev == net_ep_event_close_by_peer
           || ev == net_ep_event_close_by_error
           || ev == net_ep_event_close_by_shutdown);

    if (ep->m_fd < 0) return;

#ifdef _MSC_VER
    //if (ep->m_type = net_ep_socket) {
        net_socket_close(&ep->m_fd, ep->m_mgr->m_em);
    //}
    //else {
    //    CPE_ERROR(
    //        ep->m_mgr->m_em, "net_ep_close: close fail, errno=%d (%s)",
    //        cpe_sock_errno(), cpe_sock_errstr(cpe_sock_errno()));
    //}
#else
    if (close(ep->m_fd) != 0) {
        CPE_ERROR(
            ep->m_mgr->m_em, "net_ep_close: close fail, errno=%d (%s)",
            cpe_sock_errno(), cpe_sock_errstr(cpe_sock_errno()));
    }
#endif

    if (net_ep_calc_ev_events(ep)) {
        ev_io_stop(ep->m_mgr->m_ev_loop, &ep->m_watcher);
    }

    ep->m_fd = -1;

    if (ep->m_process_fun) ep->m_process_fun(ep, ep->m_process_ctx, ev);
}
示例#5
0
static void net_socket_int_event_callback(uint8 new_event)
{
  app_write_string("\r\n执行net socket中断事件回调函数!"); 
  if(new_event&SEND_OK)
  {
    app_write_string("\r\n执行net socket send ok!"); 
  }
  if(new_event&DIS_CONN)
  {
    app_write_string("\r\nnet tcb disconnect!");
   if(net_socket_status!=SOCKET_CLOSED)
   {
    net_socket_close();//关闭net app 重新开始
    }
  }
  if(new_event&CONNECTED)
  {
     app_write_string("\r\nnet tcb connected!");
  }
  if(new_event&TIME_OUT)
  {  
    app_write_string("\r\nnet 建立连接或者数据发送超时!");
  /*
   if(net_socket_status!=SOCKET_CLOSED)
   {
    net_socket_close();//关闭net app 重新开始
    }
    */   
  } 
}
示例#6
0
void en_socket_stream_create (EIF_INTEGER *a_fd, EIF_INTEGER *a_fd1) {
	SOCKET fd, fd1;

	EIF_NET_INITIALIZE;

	fd = check_socket_bounds(socket(AF_INET, SOCK_STREAM, 0));

	if (fd == INVALID_SOCKET) {
		*a_fd = -1;
		eif_net_check ((int)fd);
		return;
	} else {
			/* Set socket attribute so it is not passed to any child process */
		SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, FALSE);
		*a_fd = (EIF_INTEGER) fd;
	}
	if (en_ipv6_available()) {
		fd1 = check_socket_bounds(socket(AF_INET6, SOCK_STREAM, 0));
		if (fd1 == INVALID_SOCKET) {
			*a_fd = -1;
			*a_fd1 = -1;
			net_socket_close((int)fd);
			eif_net_check ((int)fd1);
			return;
		} else {
				/* Set socket attribute so it is not passed to any child process */
			SetHandleInformation((HANDLE)fd1, HANDLE_FLAG_INHERIT, FALSE);
			*a_fd1 = (EIF_INTEGER) fd1;
		}
	} else {
		*a_fd1 = -1;
	}
}
示例#7
0
void
handle_write(struct net_service* service, int ret, int err, struct write_session* wsession, size_t bytes)
{
    struct net_session* session;
    unsigned short index;
    unsigned int events;
    ffid_vtype fd;

    if(!wsession)
    {
        return;
    }
    fd = wsession->id;
    if(fd == 0)
    {
        release_write_session(wsession);
        return;
    }

    index = ffid_index(service->socket_ids, fd);
    net_lock(&service->session_lock[index]);
    session = service->sessions[index];
    wsession->op = OP_NET_NONE;
    if(ret && bytes >= 0)
    {
        send_buff_consume(wsession->sbuff, bytes);
    }

    if(!session || session->id != fd)
    {
        if(ret && wsession->send_rest && post_rest_write(service, wsession) > 0)
        {
            net_unlock(&service->session_lock[index]);
            return;
        }
        release_write_session(wsession);
        net_unlock(&service->session_lock[index]);
        return;
    }

    ret = post_write(service, session);
    events = 0;
    if(ret < 0)
    {
        events |= Eve_Error;
        print_error();
    }

    if (!events || push_queue(service, session, events) > 0)
    {
        net_unlock(&service->session_lock[index]);
        return;
    }
    net_unlock(&service->session_lock[index]);
    net_socket_close(service, fd, 0);
}
示例#8
0
loax_server_t* loax_server_new(loax_server_cmd_fn cmd_fn)
{
	assert(cmd_fn);
	LOGD("debug");

	loax_server_t* self = (loax_server_t*) malloc(sizeof(loax_server_t));
	if(self == NULL)
	{
		LOGE("malloc failed");
		return NULL;
	}

	self->w = 0;
	self->h = 0;

	// JNI callback(s)
	self->cmd_fn = cmd_fn;

	self->socket_render = net_socket_connect("localhost", "6120", NET_SOCKET_TCP_NODELAY);
	if(self->socket_render == NULL)
	{
		goto fail_render;
	}

	int retry = 0;
	while(1)
	{
		self->socket_event = net_socket_connect("localhost", "6121", NET_SOCKET_TCP_BUFFERED);
		if(self->socket_event)
		{
			break;
		}
		else if(retry == 3)
		{
			LOGE("aborted after retry=%i", retry);
			goto fail_event;
		}

		// event socket can fail if server connects too fast
		++retry;
		LOGW("retry=%i", retry);
		usleep(50000*retry);
	}

	// success
	g_server = self;   // TODO
	return self;

	// failure
	fail_event:
		net_socket_close(&self->socket_render);
	fail_render:
		free(self);
	return NULL;
}
示例#9
0
void en_socket_stream_listen (EIF_INTEGER *a_fd, EIF_INTEGER *a_fd1, EIF_POINTER sockaddr, EIF_INTEGER count) {
	int fd, fd1;
	SOCKETADDRESS *addr;
	int ipv6_supported;
	int res;

	EIF_NET_INITIALIZE;

	addr = (SOCKETADDRESS*) sockaddr;
	ipv6_supported = en_ipv6_available();

	fd = *a_fd;

	if (addr->him.sa_family == AF_INET || NET_IN6ADDR_ISANY(&addr->him6) || NET_IN6ADDR_ISLOOPBACK(&addr->him6)) {
			/* listen on v4 */
		if ((res=listen(fd, count)) == -1) {
			eif_net_check(res);
		}
	} else {
		net_socket_close(fd);
		*a_fd = -1;
	}

	if (ipv6_supported) {
		fd1 = *a_fd1;
		if ((addr->him.sa_family == AF_INET6) || (addr->him4.sin_addr.s_addr == INADDR_ANY) || (addr->him4.sin_addr.s_addr == htonl (INADDR_LOOPBACK))) {
				/* listen on v6 */
			if ((res=listen(fd1, count)) == -1) {
				eif_net_check(res);
			}
		} else {
			net_socket_close(fd1);
			*a_fd1 = -1;
		}
	}
}
示例#10
0
int main(int argc, char** argv)
{
	struct net_service* ns;
	pthread_t ts[2];
	struct net_event events[64];
	struct buff_pool* pool;
	int i;
	int ret;
	void* status;
	unsigned int e;
	struct net_config cfg;
	int count;
	param_type parm;
	char bf[1024];

	srand((unsigned)time(NULL));


	pool = buff_pool_create(1024, 64);
	if(!pool)
	{
		printf("buff_pool_create faild\n");
		exit(-1);
	}

	ns = net_create(1024 );
	if(!ns)
	{
		printf("open net_service faild\n");
		exit(-1);
	}

	for(i = 0; i < (int)(sizeof(ts)/sizeof(ts[0])); ++i)
	{
		pthread_create(ts + i, 0, thread_run, ns);
	}

	count = 0;

	while(1)
	{
		ret = net_queue(ns, events, sizeof(events)/sizeof(events[0]));
		if(ret < 0)
		{
			break;
		}
		if(ret == 0)
		{
			net_service_sleep(10);
			++count;
			
			if(!net_connect(ns, "127.0.0.1", 9522))
			{
				// printf("connect error\n");
				fflush(stdout);
			}
			
			if(count % 100 == 0)
			{
				printf("-------------------------------- %d %d %d\n", net_socket_size(ns), msg_send_count, msg_recv_count);
				fflush(stdout);
			}
			continue;
		}


		for(i = 0; i < ret; ++i)
		{
			e = events[i].events;
			if(e & Eve_Error)
			{
				printf("socket error %d  %d\n", events[i].nd, e);
				fflush(stdout);
				net_socket_close(ns, events[i].nd, 0);
				continue;
			}


			if(e & Eve_Connect)
			{
				cfg.enByte = enByte16;
				cfg.read_buff_cnt = 8;
				cfg.write_buff_cnt = 8;
				cfg.pool = pool;

				if(net_socket_cfg(ns, events[i].nd, &cfg) < 0)
				{
					net_socket_close(ns, events[i].nd, 0);
				}
				else
				{
					// add a connect
					parm = 1;
					net_socket_ctl(ns, events[i].nd , &parm);
					sprintf(bf, " s %d do some read write op  %d %d\n", net_socket_size(ns), rand(), rand());
					if(net_socket_write(ns, events[i].nd, bf, strlen(bf) + 1) > 0)
					{
						++msg_send_count;
					}
				}
			}
			
			if(e & Eve_Read)
			{
				parm = net_socket_ctl(ns, events[i].nd, 0);
				if((rand() %  20480) <  ((int)parm / 256) )
				{
					net_socket_close(ns, events[i].nd, 1);
				}
				else
				{
					++parm;
					net_socket_ctl(ns, events[i].nd, &parm);
					handle_client_read(ns, events[i].nd);
				}
			}
		}
	}

	for(i = 0; i < (int)(sizeof(ts)/sizeof(ts[0])); ++i)
	{
		pthread_join(ts[i], &status);
	}
	net_close(ns);
	buff_pool_release(pool);
	return 0;
}
示例#11
0
NET_API net_socket
net_connect(struct net_service* service, const char* ip, unsigned short port)
{
	int connect_socket;
	struct sockaddr_in connect_addr;
	struct epoll_event ev;
	struct net_session* session;
	int ret;
	ffid_vtype id;

	connect_socket = create_socket();
	if(connect_socket < 0)
	{
		return 0;
	}
	ctl_socket_async(connect_socket);


	session = create_net_session();
	if(!session)
	{
		net_close_fd(connect_socket);
		return 0;
	}
	session->fd = connect_socket;
	session->connect_flag = 1;

	id = add_net_session(service, session);
	if(!id)
	{
		release_net_session(session);
		net_close_fd(connect_socket);
		return 0;
	}

	memset(&connect_addr, 0, sizeof(connect_addr));
	connect_addr.sin_family = AF_INET;
	connect_addr.sin_addr.s_addr = inet_addr(ip);
	connect_addr.sin_port = htons(port);

	ret = connect(connect_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr));
	if(ret < 0)
	{
		ret = net_get_error();
		if(ret != EINPROGRESS)
		{
			net_socket_close_print_error();
			net_socket_close(service, id, 0);
			return 0;
		}
	}

	memset(&ev, 0, sizeof(ev));
	ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
	ev.data.u64 = session->id;
	if((ret = epoll_ctl(service->net_service_fd, EPOLL_CTL_ADD, connect_socket, &ev)))
	{
		ret = net_get_error();
		net_socket_close_print_error();
		net_socket_close(service, id, 0);
		return 0;
	}

	return id;
}
示例#12
0
NET_API net_socket
net_listen(struct net_service* service, unsigned short port, unsigned short listen_cnt)
{
	int listen_socket;
	int opt;
	struct sockaddr_in listen_addr;
	struct epoll_event ev;
	struct net_session* session;
	int ret;
	ffid_vtype id;

	listen_socket = create_socket();
	if(listen_socket < 0)
	{
		// printf("listen error step 0 %d\n", ret);
		// perror("info:");
		return 0;
	}
	opt = 1;
	// listen socket reuse
	setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
	ctl_socket_async(listen_socket);

	listen_addr.sin_family = AF_INET;
	listen_addr.sin_port = htons(port);
	listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	if((ret = bind(listen_socket, (struct sockaddr*)&listen_addr, sizeof(listen_addr))))
	{
		ret = net_get_error();
		// printf("listen error step 1 %d\n", ret);
		// perror("info:");
		net_close_fd(listen_socket);

		return 0;
	}

	if((ret = listen(listen_socket, listen_cnt)))
	{
		ret = net_get_error();
		// printf("listen error step 2 %d\n", ret);
		// perror("info:");
		net_close_fd(listen_socket);
		return 0;
	}

	session = create_net_session();
	if(!session)
	{
		// printf("listen error step 3\n");
		net_close_fd(listen_socket);
		return 0;
	}
	session->fd = listen_socket;
	session->lsession = create_listen_session(service, port, listen_cnt);
	if(!session->lsession)
	{
		// printf("listen error step 4 \n");
		release_net_session(session);
		net_close_fd(listen_socket);
		return 0;
	}

	id = add_net_session(service, session);
	if(!id)
	{
		// printf("listen error step 5 \n");
		release_net_session(session);
		net_close_fd(listen_socket);
		return 0;
	}

	memset(&ev, 0, sizeof(ev));
	ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
	ev.data.u64 = session->id;
	if((ret = epoll_ctl(service->net_service_fd, EPOLL_CTL_ADD, listen_socket, &ev)))
	{
		ret = net_get_error();
		// printf("listen error step 6 %d\n", ret);
		// perror("info:");
		net_socket_close_print_error();
		net_socket_close(service, id, 0);
		return 0;
	}
	return id;
}
示例#13
0
NET_API net_socket
net_connect(struct net_service* service, const char* ip, unsigned short port)
{
    NET_SOCKET s;
    struct sockaddr_in connect_addr;
    struct net_session* session;
    struct connect_session* csession;
    ffid_vtype id;
    FUN_CONNECTEX connectExFun;
    int err;

    s = create_socket();
    if(NET_INVALID_SOCKET == s)
    {
        return 0;
    }
    memset(&connect_addr, 0, sizeof(connect_addr));
    connect_addr.sin_family = AF_INET;
    connect_addr.sin_addr.S_un.S_addr = INADDR_ANY;
    connect_addr.sin_port = 0;

    if(bind(s, (struct sockaddr*)&connect_addr, sizeof(connect_addr)))
    {
        net_close_fd(s);
        return 0;
    }

    connectExFun = 0;
    connectExFun = get_connect_ex_fun(s);
    if(!connectExFun)
    {
        net_close_fd(s);
        return 0;
    }

    CreateIoCompletionPort((HANDLE)s, service->net_service_fd, (ULONG_PTR)s, sizeof(NET_SOCKET));

    csession = (struct connect_session*)malloc(sizeof(struct connect_session));
    if(!csession)
    {
        net_close_fd(s);
        return 0;
    }
    memset(csession, 0, sizeof(struct connect_session));
    csession->s = s;

    session = create_net_session();
    if(!session)
    {
        net_close_fd(s);
        release_connect_session(csession);
        return 0;
    }

    id = add_net_session(service, session);
    if(!id)
    {
        net_close_fd(s);
        release_net_session(session);
        release_connect_session(csession);
        return 0;
    }
    memset(&connect_addr, 0, sizeof(connect_addr));
    connect_addr.sin_family = AF_INET;
    connect_addr.sin_addr.S_un.S_addr = inet_addr(ip);
    connect_addr.sin_port = htons(port);


    csession->id = id;
    csession->op = OP_NET_CONNECT;

    session->connect_flag = 1;
    session->fd = s;
    session->data = 0;


    if(!connectExFun(s, (struct sockaddr*)&connect_addr, (int)sizeof(connect_addr),
                     0, 0, (LPDWORD)&csession->send_bytes, (LPOVERLAPPED)&csession->overlapped))
    {
        err = net_get_error();
        if(err != ERROR_IO_PENDING)
        {
            release_connect_session(csession);
            net_socket_close(service, id, 0);
            return 0;
        }
    }
    return id;
}
示例#14
0
NET_API net_socket
net_listen(struct net_service* service, unsigned short port, unsigned short listen_cnt)
{
    ffid_vtype id;
    NET_SOCKET listen_socket;
    struct net_session* session;
    struct sockaddr_in listen_addr;
    struct accept_session* asession;
    int i, ret;

    listen_socket = create_socket();
    if(NET_INVALID_SOCKET == listen_socket)
    {
        return 0;
    }
    CreateIoCompletionPort((HANDLE)listen_socket, service->net_service_fd, (ULONG_PTR)listen_socket, sizeof(NET_SOCKET));
    listen_addr.sin_family = AF_INET;
    listen_addr.sin_port = htons(port);
    listen_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    if((ret = bind(listen_socket, (struct sockaddr*)&listen_addr, sizeof(listen_addr))))
    {
        ret = net_get_error();
        net_close_fd(listen_socket);
        return 0;
    }
    if(listen(listen_socket, listen_cnt))
    {
        net_close_fd(listen_socket);
        return 0;
    }
    session = create_net_session();
    if(!session)
    {
        net_close_fd(listen_socket);
        return 0;
    }
    session->fd = listen_socket;
    session->lsession = create_listen_session(service, port, listen_cnt);
    if(!session->lsession)
    {
        release_net_session(session);
        net_close_fd(listen_socket);
        return 0;
    }

    id = add_net_session(service, session);
    if(!id)
    {
        release_net_session(session);
        net_close_fd(listen_socket);
        return 0;
    }

    for(i = 0; i < listen_cnt; ++i)
    {
        asession = create_accept_session();
        if(asession)
        {
            if(!post_listen(service, session, asession))
            {
                asession->index = i;
                continue;
            }
            release_accept_session(asession);
        }
        net_socket_close(service, id, 0);
        return 0;
    }
    return id;
}
示例#15
0
void en_socket_stream_connect (EIF_INTEGER *a_fd, EIF_INTEGER *a_fd1, EIF_INTEGER *a_local_port, EIF_POINTER sockaddr, EIF_INTEGER timeout, EIF_BOOLEAN is_blocking) {

	SOCKETADDRESS* him;
	int family;
	SOCKET fd, fd1 = INVALID_SOCKET;
	int ipv6_supported;
	int connect_res;

	EIF_NET_INITIALIZE;

	ipv6_supported = en_ipv6_available();

	fd = (SOCKET) *a_fd;
	if (ipv6_supported) {
		fd1 = *a_fd1;
	}

	him = (SOCKETADDRESS*) sockaddr;

	family = him->him.sa_family; 
	if (family == AF_INET6) {
		if (!ipv6_supported) {
			eraise ("Protocol family not supported", EN_PROG);
			return;
		} else {
			if (fd1 == -1) {
				eraise ("Destination unreachable", EN_PROG);
				return;
			}
				/* close the v4 socket, and set fd to be the v6 socket */
			*a_fd = (EIF_INTEGER) fd1;
			*a_fd1 = -1;
			net_socket_close(fd); 
			fd = fd1;
		}
	} else {
		if (fd1 != -1) {
				/* close the v6 socket */
			*a_fd1 = -1;
			net_socket_close(fd1); 
		}
		if (fd == INVALID_SOCKET) {
			eraise ("Destination unreachable", EN_PROG);
			return;
		} 
	}

	if (timeout <= 0) {
		connect_res = connect(fd, (struct sockaddr *) him, SOCKETADDRESS_LEN(him));
		if (connect_res == SOCKET_ERROR) {
			connect_res = WSAGetLastError();
			if ((connect_res == WSAEWOULDBLOCK) || (connect_res == WSAEINPROGRESS)) {
				connect_res = 0;
				errno = 0;
			}
		}
	} else {
		u_long optval;
		int optlen = sizeof(int);

			/* make socket non-blocking */
		if (is_blocking) {
			optval = 1;
			ioctlsocket( fd, FIONBIO, &optval );
		}

			/* initiate the connect */
		connect_res = connect(fd, (struct sockaddr *) him, SOCKETADDRESS_LEN(him));
		if (connect_res == SOCKET_ERROR) {
			if (WSAGetLastError() == WSAEWOULDBLOCK) {
				fd_set wr, ex;
				struct timeval t;

				FD_ZERO(&wr);
				FD_ZERO(&ex);
				FD_SET(fd, &wr);
				FD_SET(fd, &ex);
				t.tv_sec = timeout / 1000;
				t.tv_usec = (timeout % 1000) * 1000;

					/* Wait for timout, connection established or
					 * connection failed. */
				connect_res = select((int) fd+1, 0, &wr, &ex, &t);

				/* Timeout before connection is established/failed so
				 * we throw exception and shutdown input/output to prevent
				 * socket from being used.
				 * The socket should be closed immediately by the caller. */
				if (connect_res == 0) {
					shutdown( fd, SD_BOTH );
					if (is_blocking) {
							/* make socket blocking again - just in case */
						optval = 0;
						ioctlsocket( fd, FIONBIO, &optval );
					}
					eraise("connect timed out", EN_PROG);
					return;
				}

					/* We must now determine if the connection has been established
					 * or if it has failed. The logic here is designed to work around
					 * bug on Windows NT whereby using getsockopt to obtain the 
					 * last error (SO_ERROR) indicates there is no error. The workaround
					 * on NT is to allow winsock to be scheduled and this is done by
					 * yielding and retrying. As yielding is problematic in heavy
					 * load conditions we attempt up to 3 times to get the error reason. */
				if (!FD_ISSET(fd, &ex)) {
					connect_res = 0;
				} else {
					int retry;
					for (retry=0; retry<3; retry++) {
						net_get_sock_opt(fd, SOL_SOCKET, SO_ERROR, (char*)&connect_res, &optlen);
						if (connect_res) {
							break;
						}
						Sleep(0);
					}

					if (connect_res == 0) {
						eraise("Unable to establish connection", EN_PROG);
						return;
					}
				}
			}
		}

		if (is_blocking) {
				/* make socket blocking again */
			optval = 0;
			ioctlsocket(fd, FIONBIO, &optval);
		}
	}

	if (connect_res) {
		if (connect_res == WSAEADDRNOTAVAIL) {
			eraise("Address is invalid on local machine, or port is not valid on remote machine", EN_PROG);
		} else {
			eraise("Unable to establish connection", EN_PROG);
		}
		return;
	}

	*a_fd = (EIF_INTEGER) fd;

		/* we need to initialize the local port field if bind was called
		 * previously to the connect (by the client) then localport field
		 * will already be initialized. */
	if (*a_local_port == 0) {
			/* Now that we're a connected socket, let's extract the port number
			 * that the system chose for us and store it in the Socket object. */
		u_short port;
		int len = SOCKETADDRESS_LEN(him);
		if (getsockname(fd, (struct sockaddr *)him, &len) == -1) {
			if (WSAGetLastError() == WSAENOTSOCK) {
				eraise("Socket closed", EN_PROG);
			} else {
				eraise("getsockname failed", EN_PROG);
			}
			return;
		}
		port = ntohs (GET_PORT(him));
		*a_local_port = port;
	}
}