`
tcspecial
  • 浏览: 897172 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论
收藏列表
标题 标签 来源
遍历目录
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>


void listdir( char *path )
{
	DIR *dp;
    struct dirent *entry;
	char childpath[512] = {};
	
	// 目录是否存在 
    if((dp = opendir(path)) == NULL) 
		return;
	
	// 目录列表
    while( (entry = readdir(dp)) != NULL ) 
	{
        if( entry->d_type & DT_DIR ) 	// dir
		{
			// 过滤,防止死循环
            if(strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) == 0)
				continue;
           
		   // 子目录绝对路径
		   sprintf( childpath,"%s/%s",path,entry->d_name );

		   // 递归
           listdir(childpath);
        }
        else 	// file
		{
			printf("%s/%s\n",path,entry->d_name);
		}
    }

    closedir(dp);
}


int main(int argc,char **argv)
{
	listdir("/home/smart_push");
	
	return 0;
}
hash_map hash_map
#include <ext/hash_map>		// hash_map
#include <map>				// map

using namespace std;
// hash_map不是标准C++一部分,必须使用该命名空间才能使用
using namespace __gnu_cxx;	

namespace __gnu_cxx
{
	template<>
	struct hash<string>
	{
		// 对于对象或结构体类型,hash_map必须实现()运算符,而map无此限制
		size_t operator()(const string &s) const
		{
			return __stl_hash_string( s.c_str() );
		}
	};
}

/**
 * @brief hash_map使用哈希表储存数据,算法复杂度为O(1)(最快情况为O(n)),查找速度比map快
 */
void test_hashmap()
{
	// 基本类型
	hash_map<int,int> hash;
	hash[1] = 2;						// []操作符
	hash.insert( pair<int,int>(2,4) );	// pair方式
	hash.insert( make_pair(3,8) );		
        (void)hash.size();

	// string作值
	hash_map<int,string> shash;
	shash[1] = "world";

        hash_map<int,string>::iterator it = shash.find(1);	// 指针
        string k = it->second;	

	hash_map<const char*,string> chash;
	chash["hello"] = "world";

	// string作键值时比较特殊
	hash_map<string,string> sthash;
	//sthash["hello"] = "world";
	sthash.insert( make_pair(string("hello"),string("world")) );
	
	// map
	map<string,string> mp;
	mp["hello"] = "world";
}
十六进制 tohex
/**
 * 字符串转化为16进制
 *
 */
char *Str2Hex( const char *src,int count )
{
	char *dest = new char[ 2*count + 1 ];
	
    // 十六进制
    for( int i=0; i<count; i++ )
    {
        // high
        int h = ( src[i] >> 4 )&0x0f;
        if( h <= 9 )
        {
            dest[i*2] = h + '0';
        }
        else
        {
            dest[i*2] = 'a' + h - 10;
        }

        // low
        int l = src[i]&0x0f;
        if( l <= 9 )
        {
            dest[i*2+1] = l + '0';
        }
        else
        {
            dest[i*2+1] = 'a' + l - 10;
        }
    }

    dest[ count*2 ] = '\0';
	return dest;
}
校验和计算 checksum
/**
 * @brief 自动计算IP包的校验和,包括TCP部分或UDP部分。添加伪IP头部
 *
 */
int IPCheckSum( IP_HEADER* ip )
{
	if( NULL==ip || 4!=ip->Version || 5 > ip->HeadLen )
	{
		return 1;
	}

	unsigned char protocol = ip->Protocol;
	if (!(protocol==PROTOCOL_TCP || protocol==PROTOCOL_UDP))
	{
		ip->CheckSum = 0;
		ip->CheckSum = CheckSum((unsigned short*)ip, sizeof(IP_HEADER));
		return 1;
	}

	// 计算伪首部
	char* ipdata = (char*)ip + ip->HeadLen*4;
	CheckSumHeader* check = (CheckSumHeader*)(ipdata - sizeof(CheckSumHeader));

	// temp备份原数据
	char temp[sizeof(CheckSumHeader)];
	memcpy(temp, check, sizeof(CheckSumHeader));
	check->SrcIP = ip->SrcIP;
	check->DestIP = ip->DestIP;
	check->Zero = 0;
	check->Protocol = protocol;
	check->Length = htons(ntohs(ip->Length) - sizeof(IP_HEADER));

	// 计算添加伪IP头部后校验和
	if (protocol == PROTOCOL_TCP)
	{
		TCP_HEADER* tcp = (TCP_HEADER*)ipdata;
		tcp->CheckSum = 0;
		tcp->CheckSum = CheckSum((unsigned short*)check,
		ntohs(ip->Length) - sizeof(IP_HEADER) + sizeof(CheckSumHeader));
	}
	else if (protocol == PROTOCOL_UDP)
	{
		UDP_HEADER* udp = (UDP_HEADER*)ipdata;
		udp->CheckSum = 0;
		udp->CheckSum = CheckSum((unsigned short*)check,
		ntohs(ip->Length) - sizeof(IP_HEADER) + sizeof(CheckSumHeader));
	}

	// 恢复先前数据
	memcpy( check, temp, sizeof(CheckSumHeader) );

	// 计算IP校验和
	ip->CheckSum = 0;
	ip->CheckSum = CheckSum((unsigned short*)ip, sizeof(IP_HEADER));
	return 0;
}
定时器 timerfd
#include <unistd.h>
#include <stdio.h>
#include <sys/timerfd.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/epoll.h>


 
int createTimer()
{
	// 建立定时器
	int timer_id = timerfd_create( CLOCK_REALTIME,0 );
	
	struct itimerspec interval = {0};
    interval.it_value.tv_sec = 2;
    interval.it_value.tv_nsec = 0;
    interval.it_interval.tv_sec = interval.it_value.tv_sec;
    interval.it_interval.tv_nsec = interval.it_value.tv_nsec;
	
	// 设置触发时间间隔
	timerfd_settime(timer_id, 0, &interval, NULL);
	
	return timer_id;
}

void addTimer( int epfd,int timer_id )
{	
	struct epoll_event ev;
    ev.data.fd = timer_id;
    ev.events = EPOLLIN | EPOLLET;
    epoll_ctl (epfd, EPOLL_CTL_ADD, timer_id, &ev);
}

void delTimer( int epfd,int timer_id )
{
	struct epoll_event ev;
    ev.data.fd = timer_id;
    ev.events = EPOLLIN | EPOLLET;
    epoll_ctl (epfd, EPOLL_CTL_DEL, timer_id, &ev);
}


void *thread_fun( void *arg )
{
	char buf[100] = {0};
	while(1)
	{
		struct epoll_event events[5] ={0};
		int nfds = epoll_wait(epfd, events, 5, -1);
		
		int i;
		for(i=0;i<nfds;i++)
		{
			if( read( events[i].data.fd,buf,100 ) > 0 )
			{
				// 执行定时器回调函数
				printf("%d %s\n",events[i].data.fd,"hello callback");  // buf = 3
			}
		}
	}
	
	return NULL;
}


/**
 * @brief timerfd_create() 与 epoll() 配置使用示例
 * 该接口基于文件描述符,通过文件可读事件进行超时通知,能被用于select/poll场景
 * 1.新建定时器 2.设置触发时间 3.添加至epoll事件 4.epoll扫描
 */
int main(int arg,char **argv)
{
	// 扫描epoll事件
	pthread_t tid;
    pthread_create(&tid, NULL, thread_fun, NULL);
	
	// 配合timer使用
	int epfd = epoll_create(5);
	
	// 添加定时器
	int timer_id = createTimer();
	addTimer(timer_id);
	
	pause();
	return 0;
}
同步障碍 barrier
#ifndef _KCODE_BARRIER_H
#define _KCODE_BARRIER_H

/**
 * pthread_barrier_t 实现源码 
 */

#include <pthread.h>
#include <stdlib.h>


#define KBARRIER_SERIAL_THREAD -1  
  

typedef struct _kbarrier
{
	pthread_mutex_t m;
	pthread_cond_t cond;
	unsigned int cnt;
}kbarrier,*kbarrier_t;


/// 初始化
int kbarrier_init(kbarrier_t b,unsigned int cnt)
{
	kbarrier_t barrier = (kbarrier_t)malloc(sizeof(struct kbarrier));
	pthread_mutex_init(&barrier->m,NULL);
	pthread_cond_init(&barrier->cond,NULL);
	barrier->cnt = cnt;
	
	b = barrier;
	return 0;
}


/// 清理
int kbarrier_destroy(kbarrier_t b)
{
	pthread_mutext_destroy(&b->m);
	pthread_cond_destroy(&b->cond);
	
	free(b);
	
	return 0;
}


/// 计数
int kbarrier_wait(kbarrier_t b)
{
	kbarrier *impl = b;
	
	pthread_mutex_lock(&impl->m);
	
	impl->cnt--;
	if(impl->cnt ==0)
	{
		pthread_mutex_unlock(&impl->m);
		pthread_cond_broadcast(&impl->cond);   // 唤醒所有的线程
		
		return KBARRIER_SERIAL_THREAD;
	}
	
	// 线程等待
	pthread_cond_wait(&impl->cond);
	pthread_mutex_unlock(&impl->m);
	
	return 0;
}

#endif 
 
工具代码 mixture
/// 获取系统当时时间
static void GetTime()
{
	time_t rawTime;
	struct tm *tminfo;

	time(&rawTime);
	tminfo = localtime(&rawTime);  // 获取当前系统时间,相当于 QDateTime::currentDateTime().toTime_t();

	// strftime格式化
	char buffer[80];
	strftime(buffer,80,"时间:%Y-%m-%d %H:%M:%S",tminfo);
	
	// 拼凑时间字符串
	printf("当前时间串:%04d-%02d-%02d %02d:%02d:%02d\n", 
	tminfo->tm_year+1900,tminfo->tm_mon+1,tminfo->tm_mday, 
	tminfo->tm_hour,tminfo->tm_min,tminfo->tm_sec);	
}

/// memcpy实现,考虑到内存重叠的问题。更简单的方式,从后面往前面拷贝
void* my_memcpy(void *dst,void *src,size_t count)
{
	assert(dst!=NULL);
	assert(src!=NULL);

	void *dest = dst;

	if(dst<src||(char*)dst>((char*)src+count))   // 内存不重叠
	{
		while(count--)
		{
			*(char*)dst = *(char*)src;   // 赋值
			dst = (char*)dst + 1;
			src = (char*)src +1;
		}
	}else   // 内存重叠,从高位向低位拷贝
	{
		dst = (char*)dst + count-1;  // 定位到最高位
		src = (char*)src + count-1;

		while(count--)
		{
			*(char*)dst = *(char*)src;
			dst = (char*)dst -1;
			src = (char*)src -1;
		}
	}

	return dest;
}


/// 动态库加载
#ifdef WIN32
#include <windows.h>
#else
#include <dlfcn.h>  // -ldl
#endif 

typedef void (*ShowMsg)();

static void LoadLibrary() 
{
#ifdef WIN32
	HINSTANCE bDllInst=LoadLibrary("test.dll");
	if(bDllInst)
	{
		ShowMsg pMsg=(ShowMsg)GetProcAddress(bDllInst,"showMsg");
		if(pMsg)
		{
			pMsg();
		}
	}

	FreeLibrary(bDllInst);
#else

void *libHandle=dlopen("libtest.so",RTLD_LAZY);
assert(libHandle != NULL);

ShowMsg pMsg=dlsym(libHandle,"showMsg");
if(pMsg)
{
	pMsg();
}

dlclose(libHandle);

#endif
}
消息队列 msg
// msgsend.c 
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>

#define MSGKEY 1024

typedef struct _msgstu
{
	long msgtype;
	char msgtxt[2048];
}msgstu;

int main()
{
	struct msgstu msgs;
	int ret;
	int msgid;

	msgid = msgget(MSGKEY,IPC_CREAT|0666);
	assert(msgid != -1);

	msgs.msgtype = 11;
	strcpy(msgs.msgtxt,"hello world");

	// 发送
	ret=msgsnd(msgid,&msgs,sizeof(struct msgstu),IPC_NOWAIT);
	assert( ret != -1 );

	// 删除
	msgctl(msgid,IPC_RMID,0);

	return 0;
}


// msgrecv.c
int main()
{
	// 检测消息是否存在
	int msgid = msgget(MSGKEY,IPC_EXCL);
	assert(msgid != -1);

	ret=msgrcv(msgid,&msgs,sizeof(struct msgstu),0,0);
	printf("msg:%d %s\n",msgs.msgtype,msgs.msgtxt);

	return 0;
}
管道通信 pipe
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>

/**
 * @brief 单向管道,定义 O_RDWR 模式引起代码行为不可预知
 * /tmp/my_fifo
 */
int main(int argc,char **argv)
{
	int pipe_fd;
	char buffer[1024];
	strcpy(buffer,"hello world");
	
	// 管道文件不存在,则新建
	if(access(fifo_name,F_OK)==-1)
	{
		if(mkfifo (fifo_name,0777)!=0)
		{
			perror("mkfifo");
			return -1;
		}
	}

	// 堵塞
	pipe_fd = open("/tmp/my_fifo",O_WRONLY);
	assert(pipe_fd != -1);
	
	write(pipe_fd,buffer,strlen(buffer));
	return 0; 
}


/**
 *@brief 非堵塞方式操作FIFO文件
 */
int main(int argc,char **argv)
{
	int pipe_fd;
	char buffer[PIPE_BUF+1] = {};

	// 堵塞
	if((pipe_fd = open("/tmp/my_fifo",O_RDONLY))==-1)
	{
		perror("open");
		return -1;
	}
	
	// 向管道写消息
	read(pipe_fd,buffer,PIPE_BUF);
	printf("recv:%s\n",buffer);
	
	close(pipe_fd);
	return 0; 
}
Global site tag (gtag.js) - Google Analytics