简单的通信中介实现

本文介绍了一个简单的Socket通信调度器实现,该调度器用于过滤文件列表并同步处理过程。通过与HTTP服务器和Hadoop集群的交互,实现了文件上传状态的监控。

这两天净忙乎socket了,由于之前从未用过套接字,期间遇到了无数问题,当然很多都是因为手贱造成的,贴下代码和大家分享,写的不好,望斧正。

调度器简单实现(为添加日志处理和异常处理)

#include<cstdio>
#include<iostream>
#include<unistd.h>
#include<string>
#include<cstring>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<arpa/inet.h>
#include<cstdlib>
#include<mysql/mysql.h>
using namespace std;
class Scheduler{
private:
	//this enumeration save the port of component's
	enum {DB_PORT=3306,HADOOP_PORT=11000,LOCAL_PORT=12000};
	//change the ip here
	const char* ip;
	
	MYSQL mysql;
	sockaddr_in svraddr,cltaddr;
	int sockfd,listenfd,connfd;
	//communicate with mysql to check the existence of file
	void db_init();
	void db_close();
	bool check_exist(const char*);

	void svr_init();
	void clt_init();
	void conn_init();
	void svr_close();
	void clt_close();
	void conn_close();
	void filter_filelist();
	void sync_process();
public:
	void run();
};

void Scheduler::db_init(){
	mysql_init(&mysql);
	mysql_real_connect(&mysql,"localhost","root","","test",DB_PORT,NULL,0);
	//TODO:add exception procedure
}
void Scheduler::db_close(){
	mysql_close(&mysql);
}
bool Scheduler::check_exist(const char* filepath){
	string sql="select * from test where filepath='";
	sql+=filepath;
	sql+="'";
	//store the result of sql
	MYSQL_RES* res; 

	mysql_query(&mysql,sql.c_str());
	res=mysql_store_result(&mysql);
	int row=mysql_num_rows(res);
	return row;
}


void Scheduler::svr_init(){
	memset(&svraddr,0,sizeof(svraddr));
	listenfd=socket(AF_INET,SOCK_STREAM,0);

	svraddr.sin_family=AF_INET;
	svraddr.sin_addr.s_addr=htonl(INADDR_ANY);
	svraddr.sin_port=htons(LOCAL_PORT);
//TODO:add exception procedure of sock
	bind(listenfd,(sockaddr*)&svraddr,(socklen_t)sizeof(svraddr));

	listen(listenfd,10);
}

void Scheduler::clt_init(){
	memset(&cltaddr,0,sizeof(cltaddr));
	sockfd=socket(AF_INET,SOCK_STREAM,0);

	cltaddr.sin_family=AF_INET;
	cltaddr.sin_port=htons(HADOOP_PORT);
	inet_pton(AF_INET,ip,&cltaddr.sin_addr);

	connect(sockfd,(sockaddr*)&cltaddr,(socklen_t)sizeof(cltaddr));
}
void Scheduler::conn_init(){
	connfd=accept(listenfd,NULL,NULL);
}
void Scheduler::svr_close(){
	close(listenfd);
}
void Scheduler::clt_close(){
	close(sockfd);
}
void Scheduler::conn_close(){
	close(connfd);
}
void Scheduler::filter_filelist(){
	int size;
	char buf[4];
	memset(buf,0,4);

	//receive from apache httpd
	//reveive the size of list buffer
	recv(connfd,buf,4,0);
	size=*(int*)buf;
	char* list=new char[size];
	memset(list,0,size);
	//receive list
	cout<<size<<endl;
	recv(connfd,list,size,0);
	
	db_init();
	char* file=strtok(list,"$");
	string deltalist;
	while(file!=0){
		if(!check_exist(file)){
			deltalist+=file;
			deltalist+="$";
		}
		file=strtok(0,"$");
	}

	db_close();

	delete [] list;
	//includ the last zore
	size=deltalist.length();

	list=new char[size];
	memset(list,0,size);
	strncpy(list,deltalist.c_str(),size);
	list[size-1]=0;
	//send the filtered list
	send(connfd,&size,4,0);
	send(connfd,list,size,0);
	delete [] list;
}

void Scheduler::sync_process(){
	int info;
	char buf[4];
	memset(buf,0,4);
	//receeive the upload accomplish code
	recv(connfd,buf,4,0);
	info=*(int*)buf;

	if(info!=1111){
		perror("wrong info");
		exit(1);
	}

	clt_init();
	int process=0;
	char on_info='0';
	send(sockfd,&on_info,1,0);
	while(process!=100){
		memset(buf,0,4);
		recv(sockfd,buf,4,0);
		process=*(int*)buf;
		cout<<process<<endl;
		send(connfd,&process,4,0);
	}
	clt_close();
}
void Scheduler::run(){
	ip="172.16.22.89";
	svr_init();
	while(1){
		conn_init();
		filter_filelist();
		sync_process();
		conn_close();
	}
	svr_close();
}
int main(){
	Scheduler test;
	test.run();
	return 0;
}
httpd端模拟
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<unistd.h>
#include<cstring>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<netinet/in.h>
#include<arpa/inet.h>
using namespace std;
int main(){
	int sockfd;
	sockaddr_in cltaddr;

	sockfd=socket(AF_INET,SOCK_STREAM,0);
	memset(&cltaddr,0,sizeof(cltaddr));
	cltaddr.sin_family=AF_INET;
	cltaddr.sin_port=htons(12000);
	inet_pton(AF_INET, "172.16.22.89", &cltaddr.sin_addr);
	int conn=connect(sockfd,(sockaddr*)&cltaddr,(socklen_t)sizeof(cltaddr));
	if(conn<0){
		perror("error in connect");
		return 1;
	}
	int size;
	char buf[4];
	memset(buf,0,4);
	char list[]="file1$file2$file3";
	size=strlen(list)+1;
	send(sockfd,&size,4,0);
	send(sockfd,list,size,0);

	recv(sockfd,buf,4,0);
	size=*(int*)buf;
	char s[size];
	recv(sockfd,s,size,0);
	cout<<s<<endl;
	int info=1111;
	send(sockfd,&info,4,0);
	
	while(info!=100){
		memset(buf,0,4);
		recv(sockfd,buf,4,0);
		info=*(int*)buf;
		cout<<"进度:"<<info<<endl;
	}
	
	close(sockfd);
	return 0;
}
hadoop后台模拟
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<iostream>
using namespace std;
int main(int argc, char** argv)
{
    int    listenfd, connfd;
    struct sockaddr_in     servaddr;
    int     n;

    if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
    printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
    exit(0);
    }

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(11000);

    if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
    printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
    exit(0);
    }

    if( listen(listenfd, 10) == -1){
    printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
    exit(0);
    }

	cerr << "Server begin to run" << endl;
    connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
	char code;
	cerr << "Server begin to receive data" << endl;
	int recvRet = recv(connfd,&code,1,0);
	cerr << "Receive data successfully" << endl;
	cerr << "Receive value: " << recvRet << endl;
	cout<<code<<endl;
	if(code!='0'){
		exit(1);
	}
	int i;
	for(i=0;i<=100;++i){
		send(connfd,&i,4,0);
		cout<<i<<endl;
		sleep(1);
	}

	close(connfd);
    close(listenfd);
}

转载于:https://my.oschina.net/codeaxe/blog/137876

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值