Exemple #1
0
/**
 *	recv_data		- 非阻塞接收固定大小数据,在超时时间(timeout)内不接收完不返回
 *
 *	@sockfd			[in]	套接字
 *	@buf			[in]	接收数据缓存
 *	@size			[in]	接收数据大小
 *	@timeout		[in]	接收的超时时间(秒),默认为3
 *
 *	return:
 *			==	0	成功
 *			!=	0	错误码,error.h的错误码
 *
 */
int 
rcv_non_block( int sockfd, char* buf, int size, int timeout /*= 3*/)
{
	int				rsize = 0;
	int				flag, errorcode, res;

	while ( rsize != size )
	{
		errorcode = recv( sockfd, buf + rsize, size - rsize, 0 );
		if ( errorcode == 0 )
			return BUILD_ERROR(_OSerrno(), E_RCV);
		else if ( errorcode == SOCKET_ERROR )
		{
			errorcode = GetLastError();

			if ( WSAEWOULDBLOCK == errorcode )
			{
				flag	= 0x1;
				res		= select_socket( &sockfd, &flag, 1, timeout, 0 );
				if ( 0 != res )
				{
					return res;
				}
				else
					continue;
			}

			return	BUILD_ERROR(errorcode, 0);
		}

		rsize += errorcode;
	}

	return	0;
}
Exemple #2
0
/**
 *	select2sock -		用select管理两套接字
 *
 *	@cliSockInfo:	[in/out]	已建立好连接的与srv的套接字相关信息
 *	@srvSockInfo:	[in/out]	已建立好连接的与cli的套接字相关信息
 *	
 *
 *	return
 *		<0		错误码里包含具体原因(有端关闭?用户取消线程)
 */
int select2sock(SOCK_INFO &cliSockInfo, SOCK_INFO &srvSockInfo)
{
	struct timeval			tv;					/** the timeout of select*/
	fd_set					fdRead;				/** the fd_set*/
	unsigned long			toSrvBytes = 0;		/** transmit from cli to srv bytes*/
	unsigned long			toCliBytes = 0;		/** transmit from srv to cli bytes*/				
	int						ret;

	if(ret = init(cliSockInfo.sock, srvSockInfo.sock, tv) < 0)
		return ret;

	while(1)
	{
		if(USER_CANCLE)	/** cancel this thread*/
			return BUILD_ERROR(0, EFASTCLOSE);

		INIT_SELECT(fdRead, cliSockInfo.sock, srvSockInfo.sock);
		ret = select(0, &fdRead, NULL, NULL, &tv);
		switch (ret)
		{
		case SOCKET_ERROR:		/** some error happen*/
			ret = BUILD_ERROR(_OSerrno(), ESUCESS);
			break;
		case 0:					/** select timeout*/
			ret = 0;
			break;
		default:				/** need to look for fdRead and transmit*/
			ret = trsData(fdRead, cliSockInfo, srvSockInfo);
			break;
		}

		if(ret < 0)
			return ret;
	}
}
Exemple #3
0
/**
 *	setSockBuf	-	设置套接字的发送缓冲区与接收缓冲区
 *
 *	@sock:		[in]	需要设置的套接字
 *	return
 *				==0		成功
 *				< 0	失败
 */
int setSockBuf(SOCKET sock)
{
	int			optVal = SOCKET_BUFF_SIZE;
	int			optLen = sizeof(int);

	/** set recv buffer size*/
	if(setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&optVal, optLen) == SOCKET_ERROR)	
		return BUILD_ERROR(_OSerrno(), EOS);
	/** set send buffer size*/
	if(setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&optVal, optLen) == SOCKET_ERROR) 
		return BUILD_ERROR(_OSerrno(), EOS);

	return 0;
}
Exemple #4
0
/**
 *	selectSocket		- 检查描述符状态
 *
 *	@pfd			[in]所有待检查描述符数组指针
 *	@pflag			[in]所有描述符需要校验的标志位数组(每个元素的0位:可读校验;1位:可写校验;2位:err校验)
 *	@count			[in]描述符号个数
 *	@tval			[in]超时时间设置结构
 *
 *	return:
 *			==	0	成功
 *			!=	0	错误码,对应errorcode.h中定义的错误原因
 */
int select_socket(  const int* pfd,  int* pflag,  int count,  int sec, int usec )
{
	int					i, err, maxfd1 = 0;
	fd_set				fdr, fdw, fde;
	struct timeval		tval;

	FD_ZERO( &fdr );
	FD_ZERO( &fdw );
	FD_ZERO( &fde );

	for ( i = 0; i < count; i++ )
	{
		if ( pfd[i] > maxfd1 )
			maxfd1 = pfd[i];

		if ( (pflag[i] & 0x1) )
			FD_SET( (const unsigned int)pfd[i], &fdr );
		if ( (pflag[i] & 0x2) )
			FD_SET( (const unsigned int)pfd[i], &fdw );
		if ( (pflag[i] & 0x4) )
			FD_SET( (const unsigned int)pfd[i], &fde );
	}

	tval.tv_sec		= sec;
	tval.tv_usec	= usec;

	err = select( maxfd1 + 1, &fdr, &fdw, &fde, &tval );
	if ( err == SOCKET_ERROR )
	{
		return	BUILD_ERROR(_OSerrno(), E_MYABORT);
	}
	else if ( 0 == err )
		return BUILD_ERROR(0, E_TIMEOUT);

	for ( i = 0; i < count; i++ )
	{
		if ( pflag[i] & 0x1 )
			if ( !FD_ISSET( (const int)pfd[i], &fdr ) )
				pflag[i] &= (~0x1);
		if ( pflag[i] & 0x2 )
			if ( !FD_ISSET( (const int)pfd[i], &fdw ) )
				pflag[i] &= (~0x2);
		if ( pflag[i] & 0x4 )
			if ( !FD_ISSET( (const int)pfd[i], &fde ) )
				pflag[i] &= (~0x4);
	}

	return 0;
}
Exemple #5
0
/*开始监听*/
unsigned int __stdcall
smg_listen(void *in)
{
	int					lis_sock = (int)in;
	struct sockaddr_in	client;
	int					addr_size = sizeof(client);
	int					cli_sock;

	listen(lis_sock, 5);

	while(1){
		cli_sock = accept(lis_sock, (struct sockaddr *)&client, &addr_size);
		if(cli_sock == INVALID_SOCKET)
			return BUILD_ERROR(_OSerrno(), 0);
		g_log.writeLog(LOG_TYPE_INFO,
			"通过监听端口[%d] 从[%s:%d] 收到socket[%d]",
			g_option.smg_bind_port, inet_ntoa(client.sin_addr),
					ntohs(client.sin_port), cli_sock);

		/*创建线程来处理该连接*/
		_beginthreadex(NULL, 0, srv_thread, (void *)cli_sock, 0, NULL);
	}

	return 0;
}
Exemple #6
0
/**
 *	initLog		-		初始化一个日志文件
 *
 *	@handle:		[in]		全局句柄
 *	@logName:		[in]		日志文件名
 *	@logSuffix		[in]		日志文件的后缀名
 *
 *	Note:	如果传入的dir是非法的或是不存在的,该函数会返回失败
 *
 *	return
 *		0			成功
 *		<0			失败
 */
int MWriteLog::initLog(HANDLE handle, char *logName, char *logSuffix)
{
	char					szPath[256] = {0};
	char					gcCliLog[256] = {0};	/* gcClient.log的绝对路径 */
	bool					writeDisk = false;		/* 默认不写日志 */
	int						rc;
/*定义需要生成日志文件所创建的文件名(在handle所在的目录下)*/
#define		GCLOG		"gcClient.log"

	m_handle = handle;
	rc = ::GetModuleFileName((HMODULE)handle, szPath, sizeof(szPath)-1);
	if(rc == 0)
		return BUILD_ERROR(_OSerrno(), 0);

	rc = _getDir(szPath, strlen(szPath));
	if(rc != 0)
		return rc;

	rc = _snprintf(gcCliLog, sizeof(gcCliLog)-1-sizeof(GCLOG), szPath);
	if(gcCliLog[strlen(gcCliLog)-1] != '\\'){
		gcCliLog[strlen(gcCliLog)] = '\\';
		++rc;
	}
	_snprintf(gcCliLog+rc, sizeof(GCLOG), "%s", GCLOG);

	if(_access(gcCliLog, 0) != -1)/*存在*/
		writeDisk = true;

	return initLog(szPath, writeDisk, logName, logSuffix);
#undef		GCLOG
}
Exemple #7
0
/**
 *	setSockUnBlock	-	设置套接字为非阻塞
 *
 *	@sock:		[in]	需要设置的套接字
 *	return
 *				==0		成功
 *				<0	失败
 */
int setSockUnBlock(SOCKET sock)
{
	unsigned long	arg = 1;
	
	if(ioctlsocket(sock, FIONBIO, (unsigned long*)&arg) == SOCKET_ERROR)
		return BUILD_ERROR(_OSerrno(), ESETSOCK);
	
	return 0;
}
Exemple #8
0
int	
block_connect(char *ip, unsigned short port)
{
	int							err;
	struct	sockaddr_in			addrServer;

	if((err = socket(AF_INET,SOCK_STREAM,0)) == INVALID_SOCKET)
		return BUILD_ERROR(_OSerrno(), 0);

	addrServer.sin_family = AF_INET;
    addrServer.sin_addr.s_addr = inet_addr(ip);
    addrServer.sin_port = htons(port);
	
	if(connect(err,(const struct sockaddr *)&addrServer,sizeof(sockaddr)) != 0)
        return BUILD_ERROR(_OSerrno(), 0);

	return err;
}
Exemple #9
0
int	
init_network()
{
	WSADATA						wsd;
	
	if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
		return BUILD_ERROR(_OSerrno(), 0);
	
	return 0;
}
Exemple #10
0
/**
 *	send_nonblock		- 非阻塞发送固定大小数据
 *
 *	@sockfd			[in]套接字
 *	@buf			[in]发送数据缓存
 *	@size			[in]发送数据大小
 *
 *	return:
 *			==	0	成功
 *			!=	0	错误码,error.h
 */
int 
send_nonblock( int sockfd, char* buf, int size )
{
	int						rc;

	rc = send( sockfd, buf, size, 0 );
	if(rc != size)
		return BUILD_ERROR(_OSerrno(), 0);

	return	0;
}
Exemple #11
0
int
create_listen(unsigned short port)
{
	int							listen_sock;
	struct sockaddr_in			local;
	
	listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
	if (listen_sock == SOCKET_ERROR)
		return BUILD_ERROR(_OSerrno(), 0);
	
	local.sin_addr.s_addr = htonl(INADDR_ANY);
    local.sin_family = AF_INET;
    local.sin_port = htons(port);
	
	re_bind_sock(listen_sock);		/*设置重绑定*/

	if (bind(listen_sock, (struct sockaddr *)&local, 
		sizeof(local)) == SOCKET_ERROR)
		return BUILD_ERROR(_OSerrno(), 0);		/*注意:当端口被占用时,必须要返回这个错误码,用户才会重新设置监听端口*/
	
	return listen_sock;
}
Exemple #12
0
/**
 *	cliToSrv -		从客户端向服务端转发数据
 *
 *	@hs			[in]	操作数
 *	
 *	return
 *		==0		正常,不需要关闭套接字
 *		<0		出错(包括有套接字关闭)
 */
int cliToSrv(SOCK_INFO &hs)
{
	int					ret;
	char				*pSend = NULL;
	
	ret = recv(hs.sock, hs.buffer+MAX_HTTPHEAD_SIZE, MAX_IOBUFFER_LEN, 0);
	if(ret <= 0)
		return BUILD_ERROR(_OSerrno(), ECCLOSE);

	ret = buildHttpData(hs.buffer+MAX_HTTPHEAD_SIZE,
						ret,
						MAX_HTTPHEAD_SIZE,
						&pSend,
						hs.usUnitSerial,
						hs.ulLinkNo);
	if(ret < 0)
		return ret;
	
	ret = sendToPeer(hs.peerSock, pSend, ret);
	if(ret != 0)
		return BUILD_ERROR(_OSerrno(), ESCLOSE);

	return 0;
}
Exemple #13
0
int
del_report(struct msg_report &node, struct report_list &rep_list)
{
	MLocalSection			locSec;
	
	if(list_empty(&rep_list.msg_used))
		return BUILD_ERROR(0, E_LIST_EMPTY);
	
	locSec.Attch(&rep_list.msg_lock);
	struct report_node *pNode = list_entry(rep_list.msg_used.next, struct report_node, list_node);
	assert(pNode != NULL);
	memmove(&node, &(pNode->rep), sizeof(node));
	_del2insert(&(pNode->list_node), &rep_list.msg_free);
	
	return 0;
}
Exemple #14
0
int
add_report(struct msg_report &rep_msg, struct report_list &rep_list)
{
	MLocalSection			locSec;
	
	locSec.Attch(&rep_list.msg_lock);
	if(list_empty(&rep_list.msg_free))	//链表满
		return BUILD_ERROR(0, E_MSG_LEN);
	
	struct report_node	*pNode = list_entry(rep_list.msg_free.next, struct report_node, list_node);
	assert(pNode != NULL);
	memcpy(&(pNode->rep), &rep_msg, sizeof(struct msg_report));
	
	_del2insert(&(pNode->list_node), &rep_list.msg_used);


	return 0;
}
Exemple #15
0
unsigned int __stdcall 
srv_thread(void * in)
{
	int					sock = (int)in;
	assert(sock > 0);
	int					last_time = time(NULL);
	int					now_time;
	struct timeval		tv;
	fd_set				fd_read;
	int					err;

	setnonblocking(sock);	/*设置套接字非阻塞*/
	set_sock_buf(sock, 1024*64);/*设置套接字缓冲区大小*/

	tv.tv_sec = 1;
	tv.tv_usec = 0;

	while(1){
		FD_ZERO(&fd_read);
		FD_SET((unsigned int)sock, &fd_read);

		err = select(0, &fd_read, NULL, NULL, &tv);
		if(err == 0){	/*没数据,超时*/
			now_time = time(NULL);
			if(now_time - last_time > (int)g_option.sp2smg_timeout){	/*链路超时*/
				err = BUILD_ERROR(0, E_LINK_TIMEOUT);
				clean_link(sock, err);
				return err;
			}
		}else if(err > 0){
			last_time = time(NULL);
			if(FD_ISSET(sock, &fd_read)){
				err = rcv_msg2rsp(sock);
				if(err != 0){
					clean_link(sock, err);
					return err;
				}
			}else{assert(0);}
		}else{assert(0);}	/*不应该的流程*/
	}

	
	return 0;
}
Exemple #16
0
/**
 *	initLog		-		初始化一个日志文件
 *
 *	@handle						加载该日志的句柄
 *	@dir:			[in]		写日志文件的目录(非文件)
 *	@needWriteDisk:	[in]		是否需要写盘
 *	@logName:		[in]		日志文件名
 *	@logSuffix		[in]		日志文件的后缀名
 *
 *	Note:	如果传入的dir是非法的或是不存在的,该函数会返回失败
 *
 *	return
 *		0			成功
 *		<0			失败
 */
int MWriteLog::initLog(char* dir, bool writeDisk, char *logName, char *logSuffix)
{
	SYSTEMTIME					sys;
	char						logFileName[256] = {'\0'};
	int							rc;
	MLocalSection				locSec;

	InitializeCriticalSection(&m_Lock);
	
	if(dir == NULL || logName == NULL || logSuffix == NULL)
		return -1;

	locSec.Attch(&m_Lock);
	m_bNeedWriteDisk = writeDisk;
	if(m_bNeedWriteDisk == false)
		return 0;

	_snprintf(m_cLogPreName, sizeof(m_cLogPreName)-1, logName);
	_snprintf(m_cLogSuffix, sizeof(m_cLogSuffix)-1, logSuffix);

	rc = _snprintf(logFileName, sizeof(logFileName)-2, dir);
	
	if(logFileName[strlen(logFileName)-1] != '\\')
	{
		logFileName[strlen(logFileName)] = '\\';	
		++rc;
	}
	
	_snprintf(m_cLogFileDir, sizeof(m_cLogFileDir)-1, logFileName);
	
	
	GetLocalTime(&sys);
	_snprintf(logFileName+rc, sizeof(logFileName)-rc-1, 
		"%s%04d%02d%02d_%u.%s", 
		m_cLogPreName, sys.wYear,sys.wMonth,sys.wDay, m_handle, m_cLogSuffix);
	m_iLastDay = sys.wDay;
	
	m_pFile = fopen(logFileName, "a");
	if(m_pFile == NULL)
		return BUILD_ERROR(_OSerrno(), 0);

	return 0;	
}
Exemple #17
0
/**
 *	trsData -		对数据进行转发
 *
 *	@fdRead:		[in]		可读套接字集合
 *	@lhs			[in/out]	左操作数
 *	@rhs			[in/out]	右操作数
 *	
 *
 *	return
 *		==0		正常,不需要关闭套接字
 *		<0		出错(包括有一端套接字关闭)
 */
int trsData(fd_set &fdRead, SOCK_INFO &lhs, SOCK_INFO &rhs)
{
	int						ret;
	for( unsigned int i = 0; i < fdRead.fd_count; ++i )
	{	
		if(fdRead.fd_array[i] == lhs.sock)
		{
			ret = _trsData(lhs);
			if(ret != 0)	
				return ret;
		}else if(fdRead.fd_array[i] == rhs.sock)
		{
			ret = _trsData(rhs);
			if(ret != 0)
				return ret;
		}
		else
		{
			return BUILD_ERROR(0, EABORT);
		}
	}

	return 0;
}
Exemple #18
0
/** need ajusted*/
int srvToCli(SOCK_INFO &hs)
{	
	unsigned int			&leaveParased = hs.engine.leaveParased;
	HTTP_PARASE_PARAM		&httpParam = hs.engine.httpParase;
	LINE_PARASE_PARAM		&headParam = hs.engine.lineParase;	
	int						onceRecved = 0;
	int						ret;
	
	onceRecved = recv(hs.sock, hs.buffer+leaveParased, sizeof(hs.buffer)-leaveParased, 0);
	if(onceRecved <= 0)
		return BUILD_ERROR(_OSerrno(), ESCLOSE);
	/** do something with hs.HTTP_PARASE_ENG*/
	//ret = paraseHttpData(hs,);
	ret = httpParase(hs.buffer, onceRecved+leaveParased, httpParam, headParam, hs.peerSock);
	assert(ret <= onceRecved+leaveParased);
	if(ret < 0)
	{
		printf("解析出错\n");
		return ret;
	}

	if(httpParam.state == HTTP_PARASE_OK)
	{
		initState(httpParam, headParam);
// 		ret = sendToPeer(hs.peerSock, hs.buffer, ret);/** can send 0 bi*/
// 		if(ret != 0)
// 			return BUILD_ERROR(_OSerrno(), ECCLOSE);
	}


	leaveParased = onceRecved+leaveParased-ret;

	memmove(hs.buffer, hs.buffer+ret, leaveParased);

	return 0;
}
Exemple #19
0
		// returns either 0 (loaded from cache)
		// or a reason to rebuild.
		const char* fetch_cached_build(build_context *context, data *builder, build_db::record * newrecord, const char *handler_name, db::data *input, const char *path, type_handler_i *th)
		{
			// Time to hunt for cached object.
			build_db::record *record = build_db::find(builder::get_build_db(builder), path);
			if (!record)
				return "no build record found";
				
			const char *old_builder = build_db::get_builder(record);
			if (strcmp(old_builder, handler_name))
			{
				RECORD_DEBUG(newrecord, "Old builder=" << old_builder << " current=" << handler_name)
				return "builders are diffeent";
			}

			build_db::deplist *dlist = build_db::inputdeps_get(builder::get_build_db(builder), path);
			destroy_deplist destroy(dlist);

			if (!dlist)
			{
				return "no dlist";
			}

			bool gotmatch = false;

			for (int i=0;;i++)
			{
				const char *entrypath = build_db::deplist_path(dlist, i);
				if (!entrypath)
				{
					break;
				}
			
				if (!i)
				{
					RECORD_DEBUG(newrecord, "Examining cache...")
				}

				const char *signature = build_db::deplist_signature(dlist, i);
				if (!build_db::deplist_is_external_resource(dlist, i))
				{
					char inputsig[SIG_BUF_SIZE];

					if (builder->liveupdates)
					{
						strcpy(inputsig, "<broken signature>");
						db::signature(input, entrypath, inputsig);
					}
					else
					{
						if (!inputset::get_object_sig(builder->input_set, entrypath, inputsig))
						{
							if (!inputset::get_object_sig(builder->tmp_input_set, entrypath, inputsig))
							{
								BUILD_ERROR(builder, "Signature missing weirdness [" << entrypath << "]")
								strcpy(inputsig, "bonkers");
							}
						}
					}

					RECORD_DEBUG(newrecord, "=> i: " << entrypath << " old:" << signature << " new " << inputsig)

					// only care for builder match when the input is going to be built with this builder
					if (strcmp(inputsig, signature))
					{
						RECORD_DEBUG(newrecord, "!! Detected modification in [" << entrypath << "]")
						return "input or has been modified";
					}

					gotmatch = true;
				}
				else
				{