예제 #1
0
__int32 connect_nob(__int32 sockfd, const SA* saptr, socklen_t salen, __int32 nsec)
{
	__int32 n, error;                                                                                    
    socklen_t len;
    fd_set rset, wset;
    struct timeval tval;                                                                                    
    
	if (set_sock_block(sockfd, false) != 0)
		return -1;
    
    error = 0;
    if (( n = connect(sockfd, saptr, salen)) < 0) {
#ifdef WIN32
		if (getneterror() != 10035) // 非阻塞连接的正常错误
#else
		if (errno != EINPROGRESS)
#endif
            return -1;
	}
    if (n == 0)
        goto DONE; //connect completed immediately
    
    FD_ZERO(&rset);
    FD_SET (sockfd, &rset);
    wset = rset;
    tval.tv_sec = nsec;
    tval.tv_usec = 0;
    if ((n = select(sockfd+1, &rset, &wset, NULL,nsec?&tval:NULL)) == 0)                   
    {
        closesocket(sockfd);
#ifndef WIN32
        errno = ETIMEDOUT;
#endif
        return -1;
    }
    if (FD_ISSET (sockfd, &rset) || FD_ISSET(sockfd, &wset))
    {
        len = sizeof(error);
        if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&error, &len) < 0)
            return -1;
    }
    else
        return -1;

DONE:
    set_sock_block(sockfd, true);
    if (error)
    {
        closesocket(sockfd);
        errno = error;
        return -1;
    }

	return 0;
}
예제 #2
0
void im_connection::connect(const char* host, const char* serv)
{
	_host = host;
	_serv = serv;
	_state = LIBIM_DISCONNECTED;
	_fd = tcp_connect(host, serv);
	if (_fd == -1) {
		if (_ops->network_error)
			_ops->network_error(this, getneterror());
		return;
	}

	_state = LIBIM_CONNECTED;

	set_sock_block(_fd, false);

	_re = event_new(base, _fd, EV_READ|EV_PERSIST, read_cb, (void*)this);
	_we = event_new(base, _fd, EV_WRITE|EV_PERSIST, write_cb, (void*)this);
	event_add(_re, NULL);
	event_add(_we, NULL);

	_in = evbuffer_new();
	_out = evbuffer_new();

	if (_account->_imp->connect_cb)
		_account->_imp->connect_cb(this);

	if (_ops->network_connected)
		_ops->network_connected(this);
}
예제 #3
0
파일: io.c 프로젝트: CMONO/libfuncs
int do_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen, int timeout) {
	set_sock_nonblock(sockfd);
	// Trying to connect with timeout
	int result = connect(sockfd, serv_addr, addrlen);
	if (result < 0) { // Not connected
		if (errno != EINPROGRESS) { // Not in progress
			return -1;
		} else { // Wait a timeout ms for socket to become ready to write into
			struct pollfd fdset[1];
			fdset[0].fd = sockfd;
			fdset[0].events = POLLOUT | POLLERR | POLLHUP | POLLNVAL | POLLRDHUP;
			do {
				int fdready = poll(fdset, 1, timeout);
				if (fdready == -1 && errno == EINTR)
					continue;
				if (fdready < 1 || (fdready == 1 && fdset[0].revents != POLLOUT)) { // Timeout || error
					// Get socket error
					unsigned int err_val=0, sz = sizeof(int); 
					getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)(&err_val), &sz);
					errno = err_val;
					if (!errno) // It can't be success, so simulate timeout
						errno = ENETDOWN;
					return -1;
				}
				break;
			} while (1);
		}
	}
	set_sock_block(sockfd);
	return 0;
}
예제 #4
0
/*****************************************************************************
 Prototype    : main_loop
 Description  : main loop for cam ctrl server
 Input        : CamCtrlSrvEnv *envp  
 Output       : None
 Return Value : static
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2012/4/23
    Author       : Sun
    Modification : Created function

*****************************************************************************/
static Int32 main_loop(CamCtrlSrvEnv *envp)
{
	int 			ret = E_NO;
	Bool			exit = FALSE;
	int				listenSock, udpScok, fdMax;
	fd_set			rdSet;
	UdpProcEnv		udpProcEnv;

	/* alloc buffer for communication */
	envp->transBuf = calloc(1, envp->bufLen);
	assert(envp->transBuf);
	
	/* create socket */
	listenSock = socket_tcp_server(envp->tcpPort, CAM_CTRL_LISTEN_NUM);
	if(listenSock < 0) {
		ERR("create server socket failed");
		return E_IO;
	}
	/* set to non-blocking and use select for wait */
	set_sock_block(listenSock, FALSE);

	/* create udp server socket */
	udpScok = socket_udp_server(envp->udpPort);
	if(udpScok < 0) {
		ERR("create udp server socket failed");
		return E_IO;
	}
	/* set timeout */
	set_sock_send_timeout(udpScok, CAM_CTRL_TIMEOUT);
	set_sock_recv_timeout(udpScok, CAM_CTRL_TIMEOUT);
	udpProcEnv.cmdListenPort = envp->tcpPort;
	udpProcEnv.needReboot = FALSE;

	/* create icam ctrl handle */
	envp->hCamCtrl = icam_ctrl_create(CAM_CTRL_MSG, 0, CAM_CTRL_TIMEOUT);
	if(!envp->hCamCtrl) {
		ERR("create cam ctrl handle failed");
		ret = E_IO;
		goto quit;
	}

	/* init mutex for sync */
	pthread_mutex_init(&envp->mutex, NULL);
	
	/* ignore signal when socket is closed by server */
	signal(SIGPIPE, SIG_IGN); 

	DBG("%s, port %u waiting for connection...", PROGRAM_NAME, envp->tcpPort);

	/* choose max fd */
	fdMax = MAX(listenSock, udpScok) + 1;

	while(!exit) {	
		/* wait data ready */
		FD_ZERO(&rdSet);
		FD_SET(listenSock, &rdSet);
		FD_SET(udpScok, &rdSet);
		
		ret = select(fdMax, &rdSet, NULL, NULL, NULL);
		if(ret < 0 && errno != EINTR) {
			ERRSTR("select err");
			break;
		}

		/* no data ready */
		if(!ret)
			continue;

		/* check which is ready */
		if(FD_ISSET(listenSock, &rdSet)){
			/* accept connection */
			tcp_accept(envp, listenSock);
		}

		if(FD_ISSET(udpScok, &rdSet)){
			/* process udp cmd */
			udp_process(udpScok, &udpProcEnv);
			if(udpProcEnv.needReboot)
				break;
		}	
	}

quit:

	if(listenSock > 0)
		close(listenSock);

	if(envp->hCamCtrl)
		icam_ctrl_delete(envp->hCamCtrl);

	pthread_mutex_destroy(&envp->mutex);

	free(envp->transBuf);

	if(udpProcEnv.needReboot)
		system("shutdown -r now\n");
	
	return ret;
}
예제 #5
0
static void main_loop(const char *serverIp, Uint16 port)
{
	int sockTcp = socket_tcp_server(56790, 5);
	assert(sockTcp >= 0);
	int sockUdp = socket_udp_server(56790);
	assert(sockUdp >= 0);

	int err = set_sock_send_timeout(sockTcp, 5);
	err |= set_sock_recv_timeout(sockTcp, 5);
	assert(err == 0);

	err = set_sock_buf_size(sockUdp, 512 * 1024, 512 * 1024);
	err |= set_sock_linger(sockUdp, TRUE, 2);
	err |= set_sock_block(sockUdp, FALSE);
	DBG("err = %d", err);
	assert(err == 0);

	close(sockTcp);
	close(sockUdp);

	sockTcp = socket(AF_INET, SOCK_STREAM, 0);
	struct sockaddr_in addr;
	init_sock_addr(&addr, serverIp, port);

	err = connect_nonblock(sockTcp, (struct sockaddr *)&addr, sizeof(addr), 5000);
	if(err < 0) {
		ERR("Connect nonblocking server failed.");
		goto exit;
	} else {
		DBG("Connect to %s:%u success!", serverIp, port);
	}

	close(sockTcp);
	close(sockUdp);
	sockTcp = sockUdp = -1;
	
	sockTcp = socket(AF_INET, SOCK_STREAM, 0);
	err = connect(sockTcp, (struct sockaddr *)&addr, sizeof(addr));
	if(err < 0) {
		ERR("Connect server failed.");
		goto exit;
	} else {
		DBG("Connect to %s:%u success!", serverIp, port);
	}

	sockUdp = socket(AF_INET, SOCK_DGRAM, 0);
	char *sendLine = "Hello";
	err = sendto(sockUdp, sendLine, strlen(sendLine), 0, (struct sockaddr *)&addr, sizeof(addr));
	if(err < 0)
		ERR("Send to failed.");
	else
		DBG("Sendto ok...");

	char ipBuf[32];

	err = get_local_ip(ipBuf, sizeof(ipBuf));
	assert(err == E_NO);
	DBG("get local ip: %s", ipBuf);

	Uint8 macAddr[6];
	err = sys_get_mac("eth0", macAddr, sizeof(macAddr));
	assert(err == E_NO);
	DBG("get mac addr: %02X-%02X-%02X-%02X-%02X-%02X", 
		macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);

exit:

	if(sockTcp > 0)
		close(sockTcp);
	if(sockUdp > 0)
		close(sockUdp);
	
}