这两天净忙乎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);
}